diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml index ed04650291a8..569944bb53fd 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml @@ -316,6 +316,12 @@ properties: * arm/msm/qcom,kpss-acc.txt + qcom,freq-domain: + $ref: '/schemas/types.yaml#/definitions/phandle-array' + description: | + CPUs supporting freq-domain must set their "qcom,freq-domain" property + with phandle to a cpufreq_hw node followed by the Domain ID(0/1). + rockchip,pmu: $ref: '/schemas/types.yaml#/definitions/phandle' description: | diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index 129cdd246223..2b3774d05ffb 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -41,6 +41,7 @@ description: | sa8155p sc7180 sc7280 + msm8998 sdm630 sdm632 sdm660 @@ -225,6 +226,20 @@ properties: - google,senor - const: qcom,sc7280 + - items: + - enum: + - asus,novago-tp370ql + - fxtec,pro1 + - hp,envy-x2 + - lenovo,miix-630 + - oneplus,cheeseburger + - oneplus,dumpling + - qcom,msm8998-mtp + - sony,xperia-lilac + - sony,xperia-maple + - sony,xperia-poplar + - const: qcom,msm8998 + - items: - enum: - fairphone,fp3 diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml index 2f1b8b6852a0..c1f8ae620210 100644 --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml @@ -18,6 +18,10 @@ description: | properties: compatible: oneOf: + - description: Non-secure v1 of CPUFREQ HW + items: + - const: qcom,cpufreq-hw-8998 + - description: v1 of CPUFREQ HW items: - const: qcom,cpufreq-hw @@ -28,19 +32,9 @@ properties: - qcom,sm8250-cpufreq-epss - const: qcom,cpufreq-epss - reg: - minItems: 2 - items: - - description: Frequency domain 0 register region - - description: Frequency domain 1 register region - - description: Frequency domain 2 register region + reg: {} - reg-names: - minItems: 2 - items: - - const: freq-domain0 - - const: freq-domain1 - - const: freq-domain2 + reg-names: {} clocks: items: @@ -55,9 +49,52 @@ properties: '#freq-domain-cells': const: 1 +if: + properties: + compatible: + contains: + const: qcom,cpufreq-hw-8998 +then: + properties: + reg: + minItems: 2 + items: + - description: Frequency domain 0 register region + - description: Operating State Manager domain 0 register region + - description: Frequency domain 1 register region + - description: Operating State Manager domain 1 register region + - description: PLL ACD domain 0 register region (if ACD programming required) + - description: PLL ACD domain 1 register region (if ACD programming required) + + reg-names: + minItems: 2 + items: + - const: "osm-domain0" + - const: "freq-domain0" + - const: "osm-domain1" + - const: "freq-domain1" + - const: "osm-acd0" + - const: "osm-acd1" + +else: + properties: + reg: + minItems: 2 + items: + - description: Frequency domain 0 register region + - description: Frequency domain 1 register region + - description: Frequency domain 2 register region + reg-names: + minItems: 2 + items: + - const: "freq-domain0" + - const: "freq-domain1" + - const: "freq-domain2" + required: - compatible - reg + - reg-names - clocks - clock-names - '#freq-domain-cells' diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa5.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa5.yaml new file mode 100644 index 000000000000..6814598477fa --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa5.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,s6e3fa5.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung S6E3FA5 AMOLED panel with command mode DSI controller + +maintainers: + - Jami Kettunen + +description: |+ + This panel is found on the OnePlus 3T as well as OnePlus 5, + however on the 3T it runs in video mode while this driver + currently only support the command mode variant found on the + 5. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + const: samsung,s6e3fa5 + reg: true + reset-gpios: true + disp-te-gpios: true + vddio-supply: + description: vddio supply + +required: + - compatible + - reg + - vddio-supply + - reset-gpios + - disp-te-gpios + +additionalProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + panel@0 { + reg = <0>; + + compatible = "samsung,s6e3fa5"; + + vddio-supply = <&vreg_l14a_1p88>; + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + disp-te-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>; + }; + }; diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3fc1.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fc1.yaml new file mode 100644 index 000000000000..89e04d9e0f50 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fc1.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,s6e3fc1.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung S6E3FC1 AMOLED panel with command mode DSI controller + +maintainers: + - Jami Kettunen + +description: |+ + This panel is found on the OnePlus 5T and it runs in command mode. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + const: samsung,s6e3fc1 + reg: true + reset-gpios: true + disp-te-gpios: true + vddio-supply: + description: vddio supply + +required: + - compatible + - reg + - vddio-supply + - reset-gpios + - disp-te-gpios + +additionalProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + panel@0 { + reg = <0>; + + compatible = "samsung,s6e3fc1"; + + vddio-supply = <&vreg_l14a_1p88>; + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + disp-te-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt deleted file mode 100644 index dc71754a56af..000000000000 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt +++ /dev/null @@ -1,40 +0,0 @@ -Qualcomm Universal Peripheral (QUP) I2C controller - -Required properties: - - compatible: Should be: - * "qcom,i2c-qup-v1.1.1" for 8660, 8960 and 8064. - * "qcom,i2c-qup-v2.1.1" for 8974 v1. - * "qcom,i2c-qup-v2.2.1" for 8974 v2 and later. - - reg: Should contain QUP register address and length. - - interrupts: Should contain I2C interrupt. - - - clocks: A list of phandles + clock-specifiers, one for each entry in - clock-names. - - clock-names: Should contain: - * "core" for the core clock - * "iface" for the AHB clock - - - #address-cells: Should be <1> Address cells for i2c device address - - #size-cells: Should be <0> as i2c addresses have no size component - -Optional properties: - - clock-frequency: Should specify the desired i2c bus clock frequency in Hz, - defaults to 100kHz if omitted. - -Child nodes should conform to i2c bus binding. - -Example: - - i2c@f9924000 { - compatible = "qcom,i2c-qup-v2.2.1"; - reg = <0xf9924000 0x1000>; - interrupts = <0 96 0>; - - clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - - clock-frequency = <355000>; - - #address-cells = <1>; - #size-cells = <0>; - }; diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml new file mode 100644 index 000000000000..3f14dd65c6b9 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- + +$id: http://devicetree.org/schemas/i2c/qcom,i2c-qup.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Universal Peripheral (QUP) I2C controller + +maintainers: + - Andy Gross + - Bjorn Andersson + +description: Binding for Qualcomm "QUP" I2C controllers + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + +properties: + compatible: + enum: + - qcom,i2c-qup-v1.1.1 + - qcom,i2c-qup-v2.1.1 + - qcom,i2c-qup-v2.2.1 + + reg: + items: + - description: QUP I2C register iospace + + clocks: + items: + - description: Core QUP I2C clock + - description: AHB clock + + clock-names: + items: + - const: core + - const: iface + + clock-frequency: + minimum: 100000 + maximum: 1000000 + default: 100000 + + dmas: + items: + - description: RX DMA Channel phandle + - description: TX DMA Channel phandle + + dma-names: + items: + - const: rx + - const: tx + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + qcom,noise-reject-sda: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Noise rejection level for the SDA line. + minimum: 0 + maximum: 3 + default: 0 + + qcom,noise-reject-scl: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Noise rejection level for the SCL line. + minimum: 0 + maximum: 3 + default: 0 + +required: + - compatible + - clocks + - clock-names + - reg + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + i2c@c175000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x0c175000 0x600>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + clock-frequency = <400000>; + dmas = <&blsp_dma 4>, <&blsp_dma 5>; + dma-names = "rx", "tx"; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-rradc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-rradc.yaml new file mode 100644 index 000000000000..c8cbfd3444be --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-rradc.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-rradc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm's SPMI PMIC Round Robin ADC + +maintainers: + - Caleb Connolly + +description: | + The Qualcomm SPMI Round Robin ADC (RRADC) provides interface to clients to + read the voltage, current and temperature for supported peripherals such as + the battery thermistor die temperature, charger temperature, USB and DC input + voltage / current and battery ID resistor. + +properties: + compatible: + enum: + - qcom,pmi8998-rradc + - qcom,pm660-rradc + + reg: + maxItems: 1 + + qcom,batt-id-delay-ms: + description: Sets the hardware settling time for the battery ID resistor. + enum: [0, 1, 4, 12, 20, 40, 60, 80] + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pmic { + #address-cells = <1>; + #size-cells = <0>; + + pmic_rradc: adc@4500 { + compatible = "qcom,pmi8998-rradc"; + reg = <0x4500>; + #io-channel-cells = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/input/gpio-fastmatrix-keyboard.yaml b/Documentation/devicetree/bindings/input/gpio-fastmatrix-keyboard.yaml new file mode 100644 index 000000000000..3830997016c0 --- /dev/null +++ b/Documentation/devicetree/bindings/input/gpio-fastmatrix-keyboard.yaml @@ -0,0 +1,129 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/gpio-fastmatrix-keyboard.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Fast modern GPIO-driven keyboard/keypad matrix driver binding + +maintainers: + - AngeloGioacchino Del Regno + +description: | + A simple common binding for matrix-connected keyboards/keypads, targeted at + defining the keys in the scope of linux key codes since that is a stable and + standardized interface at this time. + This driver uses the GPIOD API in order to support setting (and reading) an + entire array of GPIOs which is very fast (if the controller supports it) and + a requirement to support full keyboard matrices on slow external GPIO I2C + expanders, but also a great latency enhancement for faster GPIO controllers. + +allOf: + - $ref: input.yaml# + +properties: + compatible: + const: gpio-fastmatrix-keyboard + + label: + description: Descriptive name of the key. + + linux,keymap: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: | + An array of packed 1-cell entries containing the equivalent of row, + column and linux key-code as specified in dt-bindings/input/input.h + + autorescan-ms: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Activates auto-rescanning of the matrix after receiving and processing + an event for quirky hardware that won't re-send interrupts on fast-press, + fast-depress, or multiple keys pressed events. + This time is expressed in milliseconds; if not specified, the feature is + disabled. + + col-scan-delay-us: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Time to wait in microseconds for scan after activating a column. + If not specified, the default is 0 (no wait). + + debounce-delay-ms: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Matrix button debouncing interval time in milliseconds. + If not specified, debouncing is disabled. + + drive-inactive-cols: + type: boolean + description: Keep direction of inactive columns as output + + col-gpios: + minItems: 2 + maxItems: 20 + + keypad,num-rows: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Number of row lines connected to the keypad controller. + + keypad,num-columns: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Number of column lines connected to the keypad controller. + + pinctrl-0: + maxItems: 1 + + pinctrl-names: + maxItems: 1 + + row-gpios: + minItems: 2 + maxItems: 20 + +required: + - compatible + - row-gpios + - col-gpios + - linux,keymap + - keypad,num-rows + - keypad,num-columns + +additionalProperties: true + +examples: + - | + #include + #include + + gpio-keyboard { + compatible = "gpio-fastmatrix-keyboard"; + label = "Keyboard over I2C Expander"; + row-gpios = + <&gpioext0 0 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 1 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 2 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 3 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 4 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 5 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 6 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 7 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + col-gpios = + <&gpioext0 8 GPIO_ACTIVE_LOW>, + <&gpioext0 9 GPIO_ACTIVE_LOW>, + <&gpioext0 10 GPIO_ACTIVE_LOW>, + <&gpioext0 11 GPIO_ACTIVE_LOW>, + <&gpioext0 12 GPIO_ACTIVE_LOW>, + <&gpioext0 13 GPIO_ACTIVE_LOW>, + <&gpioext0 14 GPIO_ACTIVE_LOW>, + <&gpioext0 15 GPIO_ACTIVE_LOW>; + + linux,keymap = < + MATRIX_KEY(0, 0, KEY_F1) MATRIX_KEY(1, 0, KEY_H) + MATRIX_KEY(2, 0, KEY_B) MATRIX_KEY(3, 0, KEY_7) + /* ... */ + >; + + keypad,num-rows = <8>; + keypad,num-columns = <8>; + }; diff --git a/Documentation/devicetree/bindings/input/qcom,spmi-haptics.yaml b/Documentation/devicetree/bindings/input/qcom,spmi-haptics.yaml new file mode 100644 index 000000000000..d02a30c7554c --- /dev/null +++ b/Documentation/devicetree/bindings/input/qcom,spmi-haptics.yaml @@ -0,0 +1,123 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2020 Unisoc Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/qcom,spmi-haptics.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies Inc PMI8998 spmi haptics + +maintainers: + - Caleb Connolly + +description: | + Qualcomm SPMI haptics is a peripheral on some QTI PMICs. It supports linear resonant + actuators and eccentric rotating mass type haptics commonly found in mobile devices. + It supports multiple sources of wave data such as an internal buffer, direct play + (from kernel or userspace) as well as an audio output mode. + +properties: + compatible: + items: + - enum: + - qcom,pmi8998-haptics + - qcom,pmi8996-haptics + - qcom,pmi8941-haptics + + reg: + maxItems: 1 + + interrupts: + items: + - description: short circuit interrupt + - description: play interrupt + + interrupt-names: + items: + - const: short + - const: play + + qcom,actuator-type: + description: | + The type of actuator attached to the hardware. + Allowed values are, + 0 - HAP_TYPE_LRA + 1 - HAP_TYPE_ERM + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + default: 0 + + qcom,wave-shape: + description: | + Selects the wave shape to use. + Allowed values are, + 0 - HAP_WAVE_SINE + 1 - HAP_WAVE_SQUARE + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + default: 0 + + qcom,play-mode: + description: | + Selects the play mode to use. + Allowed values are, + 0 - HAP_PLAY_DIRECT + 1 - HAP_PLAY_BUFFER + 2 - HAP_PLAY_AUDIO + 3 - HAP_PLAY_PWM + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1, 2, 3 ] + default: 2 + + qcom,wave-play-rate-us: + description: | + Wave sample durection in microseconds, 1/f where f + is the resonant frequency of the actuator. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 20475 + + qcom,brake-pattern: + minItems: 4 + maxItems: 4 + description: | + The brake pattern are the strengths of the pattern + used to brake the haptics. Allowed values are, + 0 - 0V + 1 - Vmax/4 + 2 - Vmax/2 + 3 - Vmax + $ref: /schemas/types.yaml#/definitions/uint32-array + default: [0x3, 0x3, 0x2, 0x1] + +required: + - compatible + - reg + - interrupts + - qcom,wave-play-rate-us + +additionalProperties: false + +examples: + - | + #include + #include + + spmi { + #address-cells = <1>; + #size-cells = <0>; + pmi8998_haptics: haptics@c000 { + compatible = "qcom,pmi8998-haptics"; + reg = <0xc000>; + + interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>, + <0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "short", "play"; + + qcom,wave-shape = ; + qcom,play-mode = ; + qcom,brake-pattern = <0x3 0x3 0x2 0x1>; + + status = "disabled"; + }; + }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998.yaml new file mode 100644 index 000000000000..3bea90cbe053 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998.yaml @@ -0,0 +1,158 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,msm8998.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm MSM8998 Network-On-Chip interconnect + +maintainers: + - AngeloGioacchino Del Regno + - Konrad Dybcio + +description: | + The Qualcomm MSM8998 interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +properties: + reg: + maxItems: 1 + + compatible: + enum: + - qcom,msm8998-a1noc + - qcom,msm8998-a2noc + - qcom,msm8998-bimc + - qcom,msm8998-cnoc + - qcom,msm8998-gnoc + - qcom,msm8998-mnoc + - qcom,msm8998-snoc + + '#interconnect-cells': + const: 1 + + clocks: + minItems: 1 + maxItems: 3 + + clock-names: + minItems: 1 + maxItems: 3 + +required: + - compatible + - reg + - '#interconnect-cells' + - clock-names + - clocks + +additionalProperties: false + +allOf: + - if: + properties: + compatible: + contains: + enum: + - qcom,msm8998-mnoc + then: + properties: + clocks: + items: + - description: Bus Clock. + - description: Bus A Clock. + - description: CPU-NoC High-performance Bus Clock. + clock-names: + items: + - const: bus + - const: bus_a + - const: iface + + - if: + properties: + compatible: + contains: + enum: + - qcom,msm8998-a2noc + - qcom,msm8998-bimc + - qcom,msm8998-cnoc + - qcom,msm8998-gnoc + - qcom,msm8998-snoc + then: + properties: + clocks: + items: + - description: Bus Clock. + - description: Bus A Clock. + clock-names: + items: + - const: bus + - const: bus_a + +examples: + - | + #include + #include + + bimc: interconnect@1008000 { + compatible = "qcom,msm8998-bimc"; + reg = <0x01008000 0x78000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_BIMC_CLK>, + <&rpmcc RPM_SMD_BIMC_A_CLK>; + }; + + cnoc: interconnect@1500000 { + compatible = "qcom,msm8998-cnoc"; + reg = <0x01500000 0x10000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_CNOC_CLK>, + <&rpmcc RPM_SMD_CNOC_A_CLK>; + }; + + snoc: interconnect@1625000 { + compatible = "qcom,msm8998-snoc"; + reg = <0x01625000 0x6100>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_SNOC_CLK>, + <&rpmcc RPM_SMD_SNOC_A_CLK>; + }; + + a1noc: interconnect@1669000 { + compatible = "qcom,msm8998-a1noc"; + reg = <0x01669000 0x5020>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_AGGR1_NOC_CLK>, + <&rpmcc RPM_SMD_AGGR1_NOC_A_CLK>; + }; + + a2noc: interconnect@1705000 { + compatible = "qcom,msm8998-a2noc"; + reg = <0x01705000 0xa090>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_AGGR2_NOC_CLK>, + <&rpmcc RPM_SMD_AGGR2_NOC_A_CLK>; + }; + + mnoc: interconnect@1744000 { + compatible = "qcom,msm8998-mnoc"; + reg = <0x01744000 0xb010>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a", "iface"; + clocks = <&rpmcc RPM_SMD_MMAXI_CLK>, + <&rpmcc RPM_SMD_MMAXI_A_CLK>, + <&mmcc AHB_CLK_SRC>; + }; + + gnoc: interconnect@17900000 { + compatible = "qcom,msm8998-gnoc"; + reg = <0x17900000 0xe000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&xo_board>, <&xo_board>; + }; diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml new file mode 100644 index 000000000000..336bd8e10efd --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml @@ -0,0 +1,173 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/leds-qcom-lpg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Light Pulse Generator + +maintainers: + - Bjorn Andersson + +description: > + The Qualcomm Light Pulse Generator consists of three different hardware blocks; + a ramp generator with lookup table, the light pulse generator and a three + channel current sink. These blocks are found in a wide range of Qualcomm PMICs. + +properties: + compatible: + enum: + - qcom,pm8150b-lpg + - qcom,pm8150l-lpg + - qcom,pm8916-pwm + - qcom,pm8941-lpg + - qcom,pm8994-lpg + - qcom,pmc8180c-lpg + - qcom,pmi8994-lpg + - qcom,pmi8998-lpg + + "#pwm-cells": + const: 2 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + qcom,power-source: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + power-source used to drive the output, as defined in the datasheet. + Should be specified if the TRILED block is present + enum: [0, 1, 3] + + qcom,dtest: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + description: > + A list of integer pairs, where each pair represent the dtest line the + particular channel should be connected to and the flags denoting how the + value should be outputed, as defined in the datasheet. The number of + pairs should be the same as the number of channels. + items: + items: + - description: dtest line to attach + - description: flags for the attachment + + multi-led: + type: object + $ref: leds-class-multicolor.yaml# + properties: + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + patternProperties: + "^led@[0-9a-f]$": + type: object + $ref: common.yaml# + +patternProperties: + "^led@[0-9a-f]$": + type: object + $ref: common.yaml# + + properties: + reg: true + + required: + - reg + +required: + - compatible + +additionalProperties: false + +examples: + - | + #include + + led-controller { + compatible = "qcom,pmi8994-lpg"; + + #address-cells = <1>; + #size-cells = <0>; + + qcom,power-source = <1>; + + qcom,dtest = <0 0>, + <0 0>, + <0 0>, + <4 1>; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <1>; + }; + + led@2 { + reg = <2>; + color = ; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <0>; + default-state = "on"; + }; + + led@3 { + reg = <3>; + color = ; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <2>; + }; + + led@4 { + reg = <4>; + color = ; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <3>; + }; + }; + - | + #include + + led-controller { + compatible = "qcom,pmi8994-lpg"; + + #address-cells = <1>; + #size-cells = <0>; + + qcom,power-source = <1>; + + multi-led { + color = ; + function = LED_FUNCTION_STATUS; + + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + }; + + led@2 { + reg = <2>; + color = ; + }; + + led@3 { + reg = <3>; + color = ; + }; + }; + }; + - | + pwm-controller { + compatible = "qcom,pm8916-pwm"; + #pwm-cells = <2>; + }; +... diff --git a/Documentation/devicetree/bindings/pinctrl/awinic,aw9523-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/awinic,aw9523-pinctrl.yaml new file mode 100644 index 000000000000..640d4d7e4cab --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/awinic,aw9523-pinctrl.yaml @@ -0,0 +1,139 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/awinic,aw9523-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Awinic AW9523/AW9523B I2C GPIO Expander + +maintainers: + - AngeloGioacchino Del Regno + +description: | + The Awinic AW9523/AW9523B I2C GPIO Expander featuring 16 multi-function + I/O, 256 steps PWM mode and interrupt support. + +properties: + compatible: + const: awinic,aw9523-pinctrl + + reg: + maxItems: 1 + + '#gpio-cells': + description: | + Specifying the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + gpio-controller: true + + gpio-ranges: + maxItems: 1 + + interrupt-controller: true + + interrupts: + maxItems: 1 + description: Specifies the INTN pin IRQ. + + '#interrupt-cells': + description: + Specifies the PIN numbers and Flags, as defined in defined in + include/dt-bindings/interrupt-controller/irq.h + const: 2 + + reset-gpios: + maxItems: 1 + +#PIN CONFIGURATION NODES +patternProperties: + '-pins$': + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pins: + description: + List of gpio pins affected by the properties specified in + this subnode. + items: + pattern: "^gpio([0-9]|1[0-5])$" + minItems: 1 + maxItems: 16 + + function: + description: + Specify the alternative function to be configured for the + specified pins. + + enum: [ gpio, pwm ] + + bias-disable: true + bias-pull-down: true + bias-pull-up: true + drive-open-drain: true + drive-push-pull: true + input-enable: true + input-disable: true + output-high: true + output-low: true + + required: + - pins + - function + + additionalProperties: false + +required: + - compatible + - reg + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + # Example configuration to drive pins for a keyboard matrix + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + aw9523: gpio-expander@58 { + compatible = "awinic,aw9523-pinctrl"; + reg = <0x58>; + interrupt-parent = <&tlmm>; + interrupts = <50 IRQ_TYPE_EDGE_FALLING>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&tlmm 0 0 16>; + interrupt-controller; + #interrupt-cells = <2>; + reset-gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>; + + keyboard-matrix-col-pins { + pins = "gpio8", "gpio9", "gpio10", "gpio11", + "gpio12", "gpio13", "gpio14", "gpio15"; + function = "gpio"; + input-disable; + output-low; + }; + + keyboard-matrix-row-pins { + pins = "gpio0", "gpio1", "gpio2", "gpio3", + "gpio4", "gpio5", "gpio6", "gpio7"; + function = "gpio"; + bias-pull-up; + drive-open-drain; + input-enable; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/power/supply/qcom,pmi8998-charger.yaml b/Documentation/devicetree/bindings/power/supply/qcom,pmi8998-charger.yaml new file mode 100644 index 000000000000..277c47e048b6 --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/qcom,pmi8998-charger.yaml @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/supply/qcom,pmi8998-charger.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm PMI8998/PM660 Switch-Mode Battery Charger "2" + +maintainers: + - Caleb Connolly + +properties: + compatible: + enum: + - qcom,pmi8998-charger + - qcom,pm660-charger + + reg: + maxItems: 1 + + interrupts: + maxItems: 4 + + interrupt-names: + items: + - const: usb-plugin + - const: bat-ov + - const: wdog-bark + - const: usbin-icl-change + + io-channels: + items: + - description: USB in current in uA + - description: USB in voltage in uV + + io-channel-names: + items: + - const: usbin_i + - const: usbin_v + + monitored-battery: + description: phandle to the simple-battery node + $ref: /schemas/types.yaml#/definitions/phandle + +required: + - compatible + - reg + - interrupts + - interrupt-names + - io-channels + - io-channel-names + - monitored-battery + +additionalProperties: false + +examples: + - | + #include + + pmic { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <4>; + + charger@1000 { + compatible = "qcom,pmi8998-charger"; + reg = <0x1000>; + + interrupts = <0x2 0x12 0x2 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x13 0x4 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x13 0x6 IRQ_TYPE_EDGE_RISING>, + <0x2 0x16 0x1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "usb-plugin", "bat-ov", "wdog-bark", "usbin-icl-change"; + + io-channels = <&pmi8998_rradc 3>, + <&pmi8998_rradc 4>; + io-channel-names = "usbin_i", + "usbin_v"; + + monitored-battery = <&battery>; + }; + }; diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml new file mode 100644 index 000000000000..e2753740c86b --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml @@ -0,0 +1,241 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/soc/qcom/qcom,cpr3.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Qualcomm Core Power Reduction v3/v4/Hardened (CPR3, CPR4, CPRh) + +description: | + CPR (Core Power Reduction) is a technology to reduce core power on a CPU + or other device. Each OPP of a device corresponds to a "corner" that has + a range of valid voltages for a particular frequency. While the device is + running at a particular frequency, CPR monitors dynamic factors such as + temperature, etc. and suggests or, in the CPR-Hardened case performs, + adjustments to the voltage to save power and meet silicon characteristic + requirements. + +maintainers: + - AngeloGioacchino Del Regno + +properties: + compatible: + oneOf: + - description: CPRv3 controller + items: + - const: qcom,cpr3 + - description: CPRv4 controller + items: + - const: qcom,cpr4 + - description: CPRv4-Hardened controller + items: + - enum: + - qcom,msm8998-cprh + - qcom,sdm630-cprh + - const: qcom,cprh + + reg: + description: Base address and size of the CPR controller(s) + minItems: 1 + maxItems: 2 + + interrupts: + maxItems: 1 + + clock-names: + items: + - const: "ref" + + clocks: + items: + - description: CPR reference clock + + vdd-supply: + description: Autonomous Phase Control (APC) or other power supply + + '#power-domain-cells': + const: 1 + + acc-syscon: + description: phandle to syscon for writing ACC settings + + nvmem-cells: + description: Cells containing the fuse corners and revision data + minItems: 10 + maxItems: 32 + + nvmem-cell-names: + minItems: 10 + maxItems: 32 + + operating-points-v2: true + +required: + - compatible + - reg + - clock-names + - clocks + - "#power-domain-cells" + - nvmem-cells + - nvmem-cell-names + - operating-points-v2 + +additionalProperties: false + +examples: + - | + #include + #include + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + compatible = "qcom,kryo280"; + device_type = "cpu"; + reg = <0x0 0x0>; + operating-points-v2 = <&cpu_gold_opp_table>; + power-domains = <&apc_cprh 0>; + power-domain-names = "cprh"; + }; + + cpu@100 { + compatible = "qcom,kryo280"; + device_type = "cpu"; + reg = <0x0 0x0>; + operating-points-v2 = <&cpu_silver_opp_table>; + power-domains = <&apc_cprh 1>; + power-domain-names = "cprh"; + }; + }; + + cpu_silver_opp_table: cpu-silver-opp-table { + compatible = "operating-points-v2"; + opp-shared; + + opp-1843200000 { + opp-hz = /bits/ 64 <1843200000>; + required-opps = <&cprh_opp3>; + }; + opp-1094400000 { + opp-hz = /bits/ 64 <1094400000>; + required-opps = <&cprh_opp2>; + }; + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&cprh_opp1>; + }; + }; + + cpu_gold_opp_table: cpu-gold-opp-table { + compatible = "operating-points-v2"; + opp-shared; + + opp-2208000000 { + opp-hz = /bits/ 64 <2208000000>; + required-opps = <&cprh_opp3>; + }; + opp-1113600000 { + opp-hz = /bits/ 64 <1113600000>; + required-opps = <&cprh_opp2>; + }; + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&cprh_opp1>; + }; + }; + + cprh_opp_table: cpr-hardened-opp-table { + compatible = "operating-points-v2-qcom-level"; + + cprh_opp1: opp1 { + opp-level = <1>; + qcom,opp-fuse-level = <1>; + }; + cprh_opp2: opp2 { + opp-level = <2>; + qcom,opp-fuse-level = <2>; + }; + cprh_opp3: opp3 { + opp-level = <3>; + qcom,opp-fuse-level = <2 3>; + }; + }; + + apc_cprh: power-controller@179c8000 { + compatible = "qcom,msm8998-cprh", "qcom,cprh"; + reg = <0x0179c8000 0x4000>, <0x0179c4000 0x4000>; + clocks = <&gcc GCC_HMSS_RBCPR_CLK>; + clock-names = "ref"; + + #power-domain-cells = <1>; + operating-points-v2 = <&cprh_opp_table>; + + nvmem-cells = <&cpr_efuse_speedbin>, + <&cpr_fuse_revision>, + <&cpr_quot0_pwrcl>, + <&cpr_quot1_pwrcl>, + <&cpr_quot2_pwrcl>, + <&cpr_quot3_pwrcl>, + <&cpr_quot_offset1_pwrcl>, + <&cpr_quot_offset2_pwrcl>, + <&cpr_quot_offset3_pwrcl>, + <&cpr_init_voltage0_pwrcl>, + <&cpr_init_voltage1_pwrcl>, + <&cpr_init_voltage2_pwrcl>, + <&cpr_init_voltage3_pwrcl>, + <&cpr_ro_sel0_pwrcl>, + <&cpr_ro_sel1_pwrcl>, + <&cpr_ro_sel2_pwrcl>, + <&cpr_ro_sel3_pwrcl>, + <&cpr_quot0_perfcl>, + <&cpr_quot1_perfcl>, + <&cpr_quot2_perfcl>, + <&cpr_quot3_perfcl>, + <&cpr_quot_offset1_perfcl>, + <&cpr_quot_offset2_perfcl>, + <&cpr_quot_offset3_perfcl>, + <&cpr_init_voltage0_perfcl>, + <&cpr_init_voltage1_perfcl>, + <&cpr_init_voltage2_perfcl>, + <&cpr_init_voltage3_perfcl>, + <&cpr_ro_sel0_perfcl>, + <&cpr_ro_sel1_perfcl>, + <&cpr_ro_sel2_perfcl>, + <&cpr_ro_sel3_perfcl>; + + nvmem-cell-names = "cpr_speed_bin", + "cpr_fuse_revision", + "cpr0_quotient1", + "cpr0_quotient2", + "cpr0_quotient3", + "cpr0_quotient4", + "cpr0_quotient_offset2", + "cpr0_quotient_offset3", + "cpr0_quotient_offset4", + "cpr0_init_voltage1", + "cpr0_init_voltage2", + "cpr0_init_voltage3", + "cpr0_init_voltage4", + "cpr0_ring_osc1", + "cpr0_ring_osc2", + "cpr0_ring_osc3", + "cpr0_ring_osc4", + "cpr1_quotient1", + "cpr1_quotient2", + "cpr1_quotient3", + "cpr1_quotient4", + "cpr1_quotient_offset2", + "cpr1_quotient_offset3", + "cpr1_quotient_offset4", + "cpr1_init_voltage1", + "cpr1_init_voltage2", + "cpr1_init_voltage3", + "cpr1_init_voltage4", + "cpr1_ring_osc1", + "cpr1_ring_osc2", + "cpr1_ring_osc3", + "cpr1_ring_osc4"; + }; +... diff --git a/Documentation/devicetree/bindings/soundwire/qcom,sdw.txt b/Documentation/devicetree/bindings/soundwire/qcom,sdw.txt index 51ddbc509382..b93a2b3e029d 100644 --- a/Documentation/devicetree/bindings/soundwire/qcom,sdw.txt +++ b/Documentation/devicetree/bindings/soundwire/qcom,sdw.txt @@ -22,19 +22,7 @@ board specific bus parameters. - interrupts: Usage: required Value type: - Definition: should specify the SoundWire Controller core and optional - wake IRQ - -- interrupt-names: - Usage: Optional - Value type: boolean - Value type: - Definition: should be "core" for core and "wakeup" for wake interrupt. - -- wakeup-source: - Usage: Optional - Value type: boolean - Definition: should specify if SoundWire Controller is wake up capable. + Definition: should specify the SoundWire Controller IRQ - clock-names: Usage: required diff --git a/Documentation/leds/leds-qcom-lpg.rst b/Documentation/leds/leds-qcom-lpg.rst new file mode 100644 index 000000000000..f12416f02dd8 --- /dev/null +++ b/Documentation/leds/leds-qcom-lpg.rst @@ -0,0 +1,76 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============================== +Kernel driver for Qualcomm LPG +============================== + +Description +----------- + +The Qualcomm LPG can be found in a variety of Qualcomm PMICs and consists of a +number of PWM channels, a programmable pattern lookup table and a RGB LED +current sink. + +To facilitate the various use cases, the LPG channels can be exposed as +individual LEDs, grouped together as RGB LEDs or otherwise be accessed as PWM +channels. The output of each PWM channel is routed to other hardware +blocks, such as the RGB current sink, GPIO pins etc. + +The each PWM channel can operate with a period between 27us and 384 seconds and +has a 9 bit resolution of the duty cycle. + +In order to provide support for status notifications with the CPU subsystem in +deeper idle states the LPG provides pattern support. This consists of a shared +lookup table of brightness values and per channel properties to select the +range within the table to use, the rate and if the pattern should repeat. + +The pattern for a channel can be programmed using the "pattern" trigger, using +the hw_pattern attribute. + +/sys/class/leds//hw_pattern +-------------------------------- + +Specify a hardware pattern for a Qualcomm LPG LED. + +The pattern is a series of brightness and hold-time pairs, with the hold-time +expressed in milliseconds. The hold time is a property of the pattern and must +therefor be identical for each element in the pattern (except for the pauses +described below). + +Simple pattern:: + + "255 500 0 500" + + ^ + | + 255 +----+ +----+ + | | | | ... + 0 | +----+ +---- + +----------------------> + 0 5 10 15 time (100ms) + +The LPG supports specifying a longer hold-time for the first and last element +in the pattern, the so called "low pause" and "high pause". + +Low-pause pattern:: + + "255 1000 0 500 255 500 0 500" + + ^ + | + 255 +--------+ +----+ +----+ +--------+ + | | | | | | | | ... + 0 | +----+ +----+ +----+ +---- + +-----------------------------> + 0 5 10 15 20 25 time (100ms) + +Similarily, the last entry can be stretched by using a higher hold-time on the +last entry. + +In order to save space in the shared lookup table the LPG supports "ping-pong" +mode, in which case each run through the pattern is performed by first running +the pattern forward, then backwards. This mode is automatically used by the +driver when the given pattern is a palindrome. In this case the "high pause" +denotes the wait time before the pattern is run in reverse and as such the +specified hold-time of the middle item in the pattern is allowed to have a +different hold-time. diff --git a/MAINTAINERS b/MAINTAINERS index d6d879cb0afd..fc963bd429d4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16291,6 +16291,12 @@ S: Maintained F: Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml F: drivers/soc/qcom/cpr.c +QUALCOMM CORE POWER REDUCTION v3/v4/Hardened AVS DRIVER +M: AngeloGioacchino Del Regno +S: Maintained +F: Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml +F: drivers/soc/qcom/cpr3.c + QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096 M: Ilia Lin L: linux-pm@vger.kernel.org diff --git a/arch/arm64/boot/dts/qcom/msm8998-asus-novago-tp370ql.dts b/arch/arm64/boot/dts/qcom/msm8998-asus-novago-tp370ql.dts index e204b7050441..102f3e9a79a1 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-asus-novago-tp370ql.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-asus-novago-tp370ql.dts @@ -16,20 +16,22 @@ touchpad@15 { compatible = "hid-over-i2c"; - interrupt-parent = <&tlmm>; - interrupts = <0x7b IRQ_TYPE_LEVEL_LOW>; reg = <0x15>; - hid-descr-addr = <0x0001>; - pinctrl-names = "default"; pinctrl-0 = <&touchpad>; + + interrupt-parent = <&tlmm>; + interrupts = <123 IRQ_TYPE_LEVEL_LOW>; + + hid-descr-addr = <0x0001>; }; keyboard@3a { compatible = "hid-over-i2c"; - interrupt-parent = <&tlmm>; - interrupts = <0x25 IRQ_TYPE_LEVEL_LOW>; reg = <0x3a>; + interrupt-parent = <&tlmm>; + interrupts = <37 IRQ_TYPE_LEVEL_LOW>; + hid-descr-addr = <0x0001>; }; }; @@ -37,12 +39,3 @@ &sdhc2 { cd-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>; }; - -&tlmm { - touchpad: touchpad { - config { - pins = "gpio123"; - bias-pull-up; - }; - }; -}; diff --git a/arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi b/arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi index b3b352530d76..7928b8197474 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi @@ -8,13 +8,10 @@ */ #include "msm8998.dtsi" -#include "pm8998.dtsi" #include "pm8005.dtsi" +#include "pm8998.dtsi" / { - chosen { - }; - vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; regulator-name = "vph_pwr"; @@ -37,6 +34,28 @@ }; }; +&blsp1_uart3_on { + rx { + /delete-property/ bias-disable; + /* + * Configure a pull-up on 45 (RX). This is needed to + * avoid garbage data when the TX pin of the Bluetooth + * module is in tri-state (module powered off or not + * driving the signal yet). + */ + bias-pull-up; + }; + + cts { + /delete-property/ bias-disable; + /* + * Configure a pull-down on 47 (CTS) to match the pull + * of the Bluetooth module. + */ + bias-pull-down; + }; +}; + /* * The laptop FW does not appear to support the retention state as it is * not advertised as enabled in ACPI, and enabling it in DT can cause boot @@ -74,6 +93,20 @@ cpu-idle-states = <&BIG_CPU_SLEEP_1>; }; +/* + * If EFIFB is used, enabling MMCC will cause important MMSS clocks to be cleaned + * up, because as far as Linux is concerned - they are unused. Disable it by default + * on clamshell devices, as it will break them, unless either simplefb is configured to + * hold a vote for these clocks, or panels are brought up properly, using drm/msm. + */ +&mmcc { + status = "disabled"; +}; + +&mmss_smmu { + status = "disabled"; +}; + &pcie0 { status = "okay"; }; @@ -82,20 +115,16 @@ status = "okay"; }; -&pm8005_lsid1 { - pm8005-regulators { - compatible = "qcom,pm8005-regulators"; +&pm8005_regulators { + vdd_s1-supply = <&vph_pwr>; - vdd_s1-supply = <&vph_pwr>; + pm8005_s1: s1 { /* VDD_GFX supply */ + regulator-min-microvolt = <524000>; + regulator-max-microvolt = <1100000>; + regulator-enable-ramp-delay = <500>; - pm8005_s1: s1 { /* VDD_GFX supply */ - regulator-min-microvolt = <524000>; - regulator-max-microvolt = <1100000>; - regulator-enable-ramp-delay = <500>; - - /* hack until we rig up the gpu consumer */ - regulator-always-on; - }; + /* hack until we rig up the gpu consumer */ + regulator-always-on; }; }; @@ -143,127 +172,156 @@ regulator-min-microvolt = <1352000>; regulator-max-microvolt = <1352000>; }; + vreg_s4a_1p8: s4 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-allow-set-load; }; + vreg_s5a_2p04: s5 { regulator-min-microvolt = <1904000>; regulator-max-microvolt = <2040000>; }; + vreg_s7a_1p025: s7 { regulator-min-microvolt = <900000>; regulator-max-microvolt = <1028000>; }; + vreg_l1a_0p875: l1 { regulator-min-microvolt = <880000>; regulator-max-microvolt = <880000>; regulator-allow-set-load; }; + vreg_l2a_1p2: l2 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-allow-set-load; }; + vreg_l3a_1p0: l3 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; }; + vreg_l5a_0p8: l5 { regulator-min-microvolt = <800000>; regulator-max-microvolt = <800000>; }; + vreg_l6a_1p8: l6 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <1808000>; }; + vreg_l7a_1p8: l7 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-allow-set-load; }; + vreg_l8a_1p2: l8 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; }; + vreg_l9a_1p8: l9 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; }; + vreg_l10a_1p8: l10 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; }; + vreg_l11a_1p0: l11 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; }; + vreg_l12a_1p8: l12 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + vreg_l13a_2p95: l13 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; }; + vreg_l14a_1p88: l14 { regulator-min-microvolt = <1880000>; regulator-max-microvolt = <1880000>; }; + vreg_l15a_1p8: l15 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + vreg_l16a_2p7: l16 { regulator-min-microvolt = <2704000>; regulator-max-microvolt = <2704000>; }; + vreg_l17a_1p3: l17 { regulator-min-microvolt = <1304000>; regulator-max-microvolt = <1304000>; regulator-allow-set-load; }; + vreg_l18a_2p7: l18 { regulator-min-microvolt = <2704000>; regulator-max-microvolt = <2704000>; }; + vreg_l19a_3p0: l19 { regulator-min-microvolt = <3008000>; regulator-max-microvolt = <3008000>; }; + vreg_l20a_2p95: l20 { regulator-min-microvolt = <2960000>; regulator-max-microvolt = <2960000>; regulator-allow-set-load; }; + vreg_l21a_2p95: l21 { regulator-min-microvolt = <2960000>; regulator-max-microvolt = <2960000>; regulator-allow-set-load; regulator-system-load = <800000>; }; + vreg_l22a_2p85: l22 { regulator-min-microvolt = <2864000>; regulator-max-microvolt = <2864000>; }; + vreg_l23a_3p3: l23 { regulator-min-microvolt = <3312000>; regulator-max-microvolt = <3312000>; }; + vreg_l24a_3p075: l24 { regulator-min-microvolt = <3088000>; regulator-max-microvolt = <3088000>; }; + vreg_l25a_3p3: l25 { regulator-min-microvolt = <3104000>; regulator-max-microvolt = <3312000>; regulator-allow-set-load; }; + vreg_l26a_1p2: l26 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; }; + vreg_l28_3p0: l28 { regulator-min-microvolt = <3008000>; regulator-max-microvolt = <3008000>; @@ -278,7 +336,6 @@ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; - }; }; @@ -286,17 +343,6 @@ status = "okay"; }; -&tlmm { - gpio-reserved-ranges = <0 4>, <81 4>; - - touchpad: touchpad { - config { - pins = "gpio123"; - bias-pull-up; /* pull up */ - }; - }; -}; - &sdhc2 { status = "okay"; @@ -304,8 +350,17 @@ vqmmc-supply = <&vreg_l13a_2p95>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + pinctrl-0 = <&sdc2_on &sdc2_cd>; + pinctrl-1 = <&sdc2_off &sdc2_cd>; +}; + +&tlmm { + gpio-reserved-ranges = <0 4>, <81 4>; + + touchpad: touchpad-pin { + pins = "gpio123"; + bias-pull-up; + }; }; &ufshc { @@ -341,26 +396,3 @@ vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; }; - -/* PINCTRL - board-specific pinctrl */ -&blsp1_uart3_on { - rx { - /delete-property/ bias-disable; - /* - * Configure a pull-up on 45 (RX). This is needed to - * avoid garbage data when the TX pin of the Bluetooth - * module is in tri-state (module powered off or not - * driving the signal yet). - */ - bias-pull-up; - }; - - cts { - /delete-property/ bias-disable; - /* - * Configure a pull-down on 47 (CTS) to match the pull - * of the Bluetooth module. - */ - bias-pull-down; - }; -}; diff --git a/arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts b/arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts index dc5b9b274df3..89b92972ae96 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts @@ -18,6 +18,15 @@ chassis-type = "handset"; qcom,board-id = <0x02000b 0x10>; + /* This part enables graphical output via bootloader-enabled display */ + chosen { + bootargs = "earlycon=tty0 console=tty0 clk_ignore_unused"; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + }; + /* * Until we hook up type-c detection, we * have to stick with this. But it works. @@ -46,6 +55,8 @@ gpio-kb-extra-keys { compatible = "gpio-keys"; label = "Keyboard extra keys"; + #address-cells = <1>; + #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&gpio_kb_pins_extra>; @@ -98,6 +109,39 @@ }; }; + gpio_keyboard: gpio-keyboard { + compatible = "gpio-fastmatrix-keyboard"; + label = "F(x)Tec Pro1 Hardware Keyboard"; + row-gpios = + <&gpioext0 0 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 1 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 2 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 3 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 4 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 5 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 6 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>, + <&gpioext0 7 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + + col-gpios = + <&gpioext0 8 GPIO_ACTIVE_LOW>, + <&gpioext0 9 GPIO_ACTIVE_LOW>, + <&gpioext0 10 GPIO_ACTIVE_LOW>, + <&gpioext0 11 GPIO_ACTIVE_LOW>, + <&gpioext0 12 GPIO_ACTIVE_LOW>, + <&gpioext0 13 GPIO_ACTIVE_LOW>, + <&gpioext0 14 GPIO_ACTIVE_LOW>, + <&gpioext0 15 GPIO_ACTIVE_LOW>; + keypad,num-rows = <8>; + keypad,num-columns = <8>; + + pinctrl-names = "default"; + pinctrl-0 = <&keyboard_pins_col>, <&keyboard_pins_row>; + + autorescan-ms = <5>; + debounce-delay-ms = <1>; + col-scan-delay-us = <1500>; + }; + gpio-keys { compatible = "gpio-keys"; label = "Side buttons"; @@ -177,6 +221,53 @@ }; }; + disp_vcc_vreg: disp-vcc-regulator { + compatible = "regulator-fixed"; + regulator-name = "disp_vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + disp_vddio_vreg: disp-vddio-regulator { + compatible = "regulator-fixed"; + regulator-name = "disp_vddio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + regulator-allow-set-load; + }; + + disp_vci_vreg: disp-vci-regulator { + compatible = "regulator-fixed"; + regulator-name = "disp_vci"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + regulator-allow-set-load; + }; + + disp_elvdd_vreg: disp-elvdd-regulator { + compatible = "regulator-fixed"; + regulator-name = "disp_elvdd"; + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <4600000>; + regulator-boot-on; + regulator-always-on; + }; + + disp_elvss_vreg: disp-elvss-regulator { + compatible = "regulator-fixed"; + regulator-name = "disp_elvss"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <2400000>; + regulator-boot-on; + regulator-always-on; + }; + ts_vio_vreg: ts-vio-vreg { compatible = "regulator-fixed"; regulator-name = "ts_vio_reg"; @@ -189,8 +280,62 @@ }; }; +&adreno_gpu { + status = "okay"; + + zap-shader { + memory-region = <&zap_shader_region>; + firmware-name = "qcom/a540_zap.mbn"; + }; +}; + +&adreno_smmu { + status = "okay"; +}; + +&apc_cprh { + status = "okay"; +}; + +&blsp1_i2c6 { + status = "okay"; + + gpioext0: gpio-expander@58 { + compatible = "awinic,aw9523-pinctrl"; + reg = <0x58>; + interrupt-parent = <&tlmm>; + interrupts = <50 IRQ_TYPE_EDGE_FALLING>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpioext0 0 0 16>; + interrupt-controller; + #interrupt-cells = <2>; + + pinctrl-0 = <&gpio_expander_int_n>, <&gpio_expander_rst_n>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>; + + keyboard_pins_col: keyboard-matrix-col-pins { + pins = "gpio8", "gpio9", "gpio10", "gpio11", + "gpio12", "gpio13", "gpio14", "gpio15"; + function = "gpio"; + output-low; + }; + keyboard_pins_row: keyboard-matrix-row-pins { + pins = "gpio0", "gpio1", "gpio2", "gpio3", + "gpio4", "gpio5", "gpio6", "gpio7"; + function = "gpio"; + drive-open-drain; + input-enable; + }; + }; +}; + &blsp2_i2c1 { - status = "ok"; + status = "okay"; + qcom,noise-reject-scl = <3>; + qcom,noise-reject-sda = <3>; touchscreen@14 { compatible = "goodix,gt9286"; @@ -205,15 +350,141 @@ }; }; -&mmcc { - status = "ok"; +&cpufreq_hw { + status = "okay"; }; -&mmss_smmu { - status = "ok"; +&dsi0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + vdd-supply = <&vreg_l1a_0p875>; + vdda-supply = <&vreg_l2a_1p2>; + + panel: panel@0 { + compatible = "boe,bf060y8m-aj0"; + reg = <0>; + + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + disp-te-gpios = <&tlmm 10 GPIO_ACTIVE_LOW>; + no-hpd; + + vcc-supply = <&disp_vcc_vreg>; + vddio-supply = <&disp_vddio_vreg>; + vci-supply = <&disp_vci_vreg>; + elvdd-supply = <&disp_elvdd_vreg>; + elvss-supply = <&disp_elvss_vreg>; + + pinctrl-names = "default"; + pinctrl-0 = <&panel_reset_n &disp_en_default &mdp_vsync_n>; + port { + panel_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; +}; + +&dsi0_phy { + status = "okay"; +}; + +&dsi0_out { + remote-endpoint = <&panel_in>; + data-lanes = <0 1 2 3>; +}; + +&gcc { + status = "okay"; +}; + +&gpucc { + status = "okay"; +}; + +&gpio_keyboard { + linux,keymap = < + MATRIX_KEY(0, 0, KEY_F1) MATRIX_KEY(1, 0, KEY_H) + MATRIX_KEY(2, 0, KEY_B) MATRIX_KEY(3, 0, KEY_7) + MATRIX_KEY(4, 0, KEY_UP) MATRIX_KEY(5, 0, KEY_ENTER) + MATRIX_KEY(6, 0, KEY_Y) MATRIX_KEY(7, 0, KEY_COMMA) + MATRIX_KEY(0, 1, KEY_3) MATRIX_KEY(1, 1, KEY_S) + MATRIX_KEY(2, 1, KEY_Z) MATRIX_KEY(3, 1, KEY_M) + MATRIX_KEY(4, 1, KEY_I) MATRIX_KEY(5, 1, KEY_9) + MATRIX_KEY(6, 1, KEY_W) MATRIX_KEY(7, 1, KEY_J) + MATRIX_KEY(0, 2, KEY_LEFT) MATRIX_KEY(1, 2, KEY_G) + MATRIX_KEY(2, 2, KEY_V) MATRIX_KEY(3, 2, KEY_6) + MATRIX_KEY(4, 2, KEY_RIGHT) MATRIX_KEY(5, 2, KEY_DELETE) + MATRIX_KEY(6, 2, KEY_T) MATRIX_KEY(7, 2, KEY_DOT) + MATRIX_KEY(0, 3, KEY_SLASH) MATRIX_KEY(1, 3, KEY_A) + MATRIX_KEY(2, 3, KEY_RIGHTBRACE) MATRIX_KEY(3, 3, KEY_HOMEPAGE) + MATRIX_KEY(4, 3, KEY_P) MATRIX_KEY(5, 3, KEY_MINUS) + MATRIX_KEY(6, 3, KEY_Q) MATRIX_KEY(7, 3, KEY_L) + MATRIX_KEY(0, 4, KEY_BACKSPACE) MATRIX_KEY(1, 4, KEY_D) + MATRIX_KEY(2, 4, KEY_X) MATRIX_KEY(3, 4, KEY_K) + MATRIX_KEY(4, 4, KEY_SEMICOLON) MATRIX_KEY(5, 4, KEY_EQUAL) + MATRIX_KEY(6, 4, KEY_E) MATRIX_KEY(7, 4, KEY_APOSTROPHE) + MATRIX_KEY(0, 5, KEY_CAPSLOCK) MATRIX_KEY(1, 5, KEY_BACKSLASH) + MATRIX_KEY(2, 5, KEY_LEFTBRACE) MATRIX_KEY(3, 5, KEY_DOWN) + MATRIX_KEY(4, 5, KEY_O) MATRIX_KEY(5, 5, KEY_0) + MATRIX_KEY(6, 5, KEY_GRAVE) MATRIX_KEY(7, 5, KEY_K) + MATRIX_KEY(0, 6, KEY_SPACE) MATRIX_KEY(1, 6, KEY_F) + MATRIX_KEY(2, 6, KEY_C) MATRIX_KEY(3, 6, KEY_N) + MATRIX_KEY(4, 6, KEY_U) MATRIX_KEY(5, 6, KEY_8) + MATRIX_KEY(6, 6, KEY_R) MATRIX_KEY(7, 6, KEY_5) + MATRIX_KEY(0, 7, KEY_ESC) MATRIX_KEY(1, 7, KEY_1) + MATRIX_KEY(2, 7, KEY_RESERVED) MATRIX_KEY(3, 7, KEY_RESERVED) + MATRIX_KEY(4, 7, KEY_2) MATRIX_KEY(5, 7, KEY_4) + MATRIX_KEY(6, 7, KEY_TAB) MATRIX_KEY(7, 7, KEY_RESERVED) + >; +}; + +&mdss { + status = "okay"; +}; + +&mdss_mdp { + status = "okay"; +}; + +&remoteproc_adsp { + status = "okay"; + + firmware-name = "qcom/msm8998/fxtec/adsp.mbn"; +}; + +&remoteproc_mss { + firmware-name = "qcom/msm8998/fxtec/mba.mbn", "qcom/msm8998/fxtec/modem.mbn"; +}; + +&remoteproc_slpi { + status = "okay"; + + firmware-name = "qcom/msm8998/fxtec/slpi_v2.mbn"; +}; + +&pmi8998_haptics { + status = "okay"; + + qcom,wave-play-rate-us = <5000>; +}; + +/* HACK! Push GPU voltage high until GPU CPR is hooked up */ +&pm8005_s1 { + regulator-min-microvolt = <988000>; + regulator-max-microvolt = <1100000>; }; &pm8998_gpio { + unknown_pin_a: unk-active { + pins = "gpio5"; + function = "normal"; + input-enable; + bias-pull-up; + qcom,drive-strength = ; + }; + vol_up_pin_a: vol-up-active { pins = "gpio6"; function = "normal"; @@ -267,6 +538,26 @@ bias-pull-up; }; + gpio_expander_int_n: gpio-exp-intn-def { + pins = "gpio50"; + function = "gpio"; + drive-strength = <2>; + input-enable; + }; + + gpio_expander_rst_n: gpio-exp-rst-def { + pins = "gpio51"; + function = "gpio"; + drive-strength = <8>; + }; + + disp_en_default: disp-en { + pins = "gpio62"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + ts_vio_default: ts-vio-def { pins = "gpio81"; function = "gpio"; @@ -295,14 +586,21 @@ bias-disable; drive-strength = <8>; }; + + panel_reset_n: panel-rst-n { + pins = "gpio94"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; }; &ufshc { - status = "ok"; + status = "okay"; }; &ufsphy { - status = "ok"; + status = "okay"; }; &usb3_dwc3 { diff --git a/arch/arm64/boot/dts/qcom/msm8998-hp-envy-x2.dts b/arch/arm64/boot/dts/qcom/msm8998-hp-envy-x2.dts index 1eb406b43fd7..38389c6a3f68 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-hp-envy-x2.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-hp-envy-x2.dts @@ -16,13 +16,14 @@ keyboard@3a { compatible = "hid-over-i2c"; - interrupt-parent = <&tlmm>; - interrupts = <0x79 IRQ_TYPE_LEVEL_LOW>; reg = <0x3a>; - hid-descr-addr = <0x0001>; - pinctrl-names = "default"; pinctrl-0 = <&touchpad>; + + interrupt-parent = <&tlmm>; + interrupts = <121 IRQ_TYPE_LEVEL_LOW>; + + hid-descr-addr = <0x0001>; }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8998-lenovo-miix-630.dts b/arch/arm64/boot/dts/qcom/msm8998-lenovo-miix-630.dts index f55f6f3e3e5d..cf81c33a9d7e 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-lenovo-miix-630.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-lenovo-miix-630.dts @@ -16,13 +16,14 @@ keyboard@3a { compatible = "hid-over-i2c"; - interrupt-parent = <&tlmm>; - interrupts = <0x79 IRQ_TYPE_LEVEL_LOW>; reg = <0x3a>; - hid-descr-addr = <0x0001>; - pinctrl-names = "default"; pinctrl-0 = <&touchpad>; + + interrupt-parent = <&tlmm>; + interrupts = <121 IRQ_TYPE_LEVEL_LOW>; + + hid-descr-addr = <0x0001>; }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi index af67c641df4e..8368af2d78e1 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi @@ -348,8 +348,8 @@ vqmmc-supply = <&vreg_l13a_2p95>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + pinctrl-0 = <&sdc2_on &sdc2_cd>; + pinctrl-1 = <&sdc2_off &sdc2_cd>; }; &stm { diff --git a/arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dts b/arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dts index 9563eb62db88..64e8d3b0ccec 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dts @@ -41,3 +41,19 @@ }; }; }; + +/* Capacitive keypad buttons */ +&rmi4_i2c { + rmi4-f1a@1a { + reg = <0x1a>; + syna,codes = ; + }; +}; + +/* Display */ +&panel { + compatible = "samsung,s6e3fa5"; + + /* The panel is mounted upside down on the OnePlus 5 */ + rotation = <180>; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi index 9823d48a91b1..8594eca80a5a 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi @@ -9,11 +9,12 @@ /dts-v1/; #include +#include #include #include "msm8998.dtsi" +#include "pm8005.dtsi" #include "pm8998.dtsi" #include "pmi8998.dtsi" -#include "pm8005.dtsi" / { /* Required for bootloader to select correct board */ @@ -32,6 +33,20 @@ height = <1920>; stride = <(1080 * 4)>; format = "a8r8g8b8"; + /* + * That's a lot of clocks, but it's necessary due + * to unused clk cleanup & no panel driver yet.. + */ + clocks = <&mmcc MDSS_AHB_CLK>, + <&mmcc MDSS_AXI_CLK>, + <&mmcc MDSS_VSYNC_CLK>, + <&mmcc MDSS_MDP_CLK>, + <&mmcc MDSS_BYTE0_CLK>, + <&mmcc MDSS_BYTE0_INTF_CLK>, + <&mmcc MDSS_PCLK0_CLK>, + <&mmcc MDSS_ESC0_CLK>; + power-domains = <&mmcc MDSS_GDSC>; + status = "disabled"; }; }; @@ -67,6 +82,15 @@ reg = <0x0 0xf6900000 0x0 0x2000>; no-map; }; + + blp637_bat: battery { + compatible = "simple-battery"; + voltage-max-design-microvolt = <4370000>; + voltage-min-design-microvolt = <3700000>; + charge-full-design-microamp-hours = <3300000>; + energy-full-design-microwatt-hours = <12700000>; + operating-range-celsius = <0 45>; + }; }; gpio-keys { @@ -152,10 +176,18 @@ reg = <0x0 0x95715000 0x0 0x100000>; }; +&apc_cprh { + status = "okay"; +}; + +&cpufreq_hw { + status = "okay"; +}; + &blsp1_i2c5 { status = "okay"; - touchscreen@20 { + rmi4_i2c: touchscreen@20 { compatible = "syna,rmi4-i2c"; reg = <0x20>; #address-cells = <1>; @@ -188,6 +220,29 @@ }; }; +&blsp1_i2c5_sleep { + /delete-property/ bias-pull-up; + /* Configure a no-pull on TP I2C sleep to match downstream. */ + bias-disable; +}; + +&blsp1_i2c6 { + status = "okay"; + + nfc@28 { + compatible = "nxp,nxp-nci-i2c"; + reg = <0x28>; + + interrupt-parent = <&tlmm>; + interrupts = <92 IRQ_TYPE_LEVEL_HIGH>; + + enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&nfc_int_active &nfc_enable_active>; + }; +}; + &blsp1_uart3 { status = "okay"; @@ -224,39 +279,88 @@ }; }; +&blsp2_i2c1 { + status = "okay"; + + fuel-gauge@55 { + compatible = "ti,bq27411"; + reg = <0x55>; + + /* + * TODO: Adding this appears to not change any reported stats in: + * $ cat /sys/class/power_supply/bq27411-0/uevent + */ + monitored-battery = <&blp637_bat>; + }; +}; + +&blsp2_i2c3 { + status = "disabled"; + + audio-codec@36 { + compatible = "nxp,tfa9890"; + reg = <0x36>; + + /* + * vddd-supply = <&vreg_bob>; + * vreg_l20a_2p95? 2950000->2960000 mV @ 200->800000 mA? + */ + + sound-name-prefix = "Mono Speaker"; + #sound-dai-cells = <0>; + status = "disabled"; + }; +}; + &blsp2_uart1 { status = "okay"; }; -&pm8005_lsid1 { - pm8005-regulators { - compatible = "qcom,pm8005-regulators"; +&ipa { + status = "okay"; - vdd_s1-supply = <&vph_pwr>; + memory-region = <&ipa_fws_region>; // ipa_fw_mem? ipa_gsi_mem? + firmware-name = "qcom/msm8998/oneplus/ipa_fws.mbn"; +}; - pm8005_s1: s1 { /* VDD_GFX supply */ - regulator-min-microvolt = <524000>; - regulator-max-microvolt = <1100000>; - regulator-enable-ramp-delay = <500>; - - /* hack until we rig up the gpu consumer */ - regulator-always-on; - }; +&pm8005_regulators { + /* VDD_GFX supply */ + pm8005_s1: s1 { + regulator-min-microvolt = <524000>; + regulator-max-microvolt = <1100000>; + regulator-enable-ramp-delay = <500>; + /* Hack until we rig up the gpu consumer */ + regulator-always-on; }; }; &pm8998_gpio { vol_keys_default: vol-keys-default { - pinconf { - pins = "gpio5", "gpio6"; - function = "normal"; - bias-pull-up; - input-enable; - qcom,drive-strength = ; - }; + pins = "gpio5", "gpio6"; + function = "normal"; + bias-pull-up; + input-enable; + qcom,drive-strength = ; }; }; +&pmi8998_haptics { + status = "okay"; + + qcom,wave-play-rate-us = <4255>; +}; + +&pmi8998_charger { + status = "okay"; + + monitored-battery = <&blp637_bat>; +}; + +// cat /sys/bus/iio/devices/iio:device0/in_current0_* +&pmi8998_rradc { + status = "okay"; +}; + &qusb2phy { status = "okay"; @@ -269,30 +373,18 @@ pm8998-regulators { compatible = "qcom,rpm-pm8998-regulators"; - vdd_s1-supply = <&vph_pwr>; - vdd_s2-supply = <&vph_pwr>; + vdd_s1-supply = <&vph_pwr>; /* GPU? */ vdd_s3-supply = <&vph_pwr>; vdd_s4-supply = <&vph_pwr>; vdd_s5-supply = <&vph_pwr>; - vdd_s6-supply = <&vph_pwr>; vdd_s7-supply = <&vph_pwr>; - vdd_s8-supply = <&vph_pwr>; - vdd_s9-supply = <&vph_pwr>; - vdd_s10-supply = <&vph_pwr>; - vdd_s11-supply = <&vph_pwr>; - vdd_s12-supply = <&vph_pwr>; - vdd_s13-supply = <&vph_pwr>; - vdd_l1_l27-supply = <&vreg_s7a_1p025>; - vdd_l2_l8_l17-supply = <&vreg_s3a_1p35>; - vdd_l3_l11-supply = <&vreg_s7a_1p025>; - vdd_l4_l5-supply = <&vreg_s7a_1p025>; + vdd_l1-supply = <&vreg_s7a_1p025>; + vdd_l2_l17-supply = <&vreg_s3a_1p35>; + vdd_l5-supply = <&vreg_s7a_1p025>; vdd_l6-supply = <&vreg_s5a_2p04>; - vdd_l7_l12_l14_l15-supply = <&vreg_s5a_2p04>; - vdd_l9-supply = <&vreg_bob>; - vdd_l10_l23_l25-supply = <&vreg_bob>; - vdd_l13_l19_l21-supply = <&vreg_bob>; - vdd_l16_l28-supply = <&vreg_bob>; - vdd_l18_l22-supply = <&vreg_bob>; + vdd_l7_l12_l14-supply = <&vreg_s5a_2p04>; + vdd_l25-supply = <&vreg_bob>; + vdd_l28-supply = <&vreg_bob>; vdd_l20_l24-supply = <&vreg_bob>; vdd_l26-supply = <&vreg_s3a_1p35>; vdd_lvs1_lvs2-supply = <&vreg_s4a_1p8>; @@ -301,127 +393,90 @@ regulator-min-microvolt = <1352000>; regulator-max-microvolt = <1352000>; }; + vreg_s4a_1p8: s4 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-allow-set-load; }; + vreg_s5a_2p04: s5 { regulator-min-microvolt = <1904000>; regulator-max-microvolt = <2040000>; }; + vreg_s7a_1p025: s7 { regulator-min-microvolt = <900000>; regulator-max-microvolt = <1028000>; }; - vreg_l1a_0p875: l1 { + + vreg_l1a_0p875: l1 { /* UFS PHY */ regulator-min-microvolt = <880000>; regulator-max-microvolt = <880000>; }; - vreg_l2a_1p2: l2 { + + vreg_l2a_1p2: l2 { /* UFS PHY */ regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; }; - vreg_l3a_1p0: l3 { - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1000000>; - }; - vreg_l5a_0p8: l5 { + + vreg_l5a_0p8: l5 { /* Wi-Fi */ regulator-min-microvolt = <800000>; regulator-max-microvolt = <800000>; }; - vreg_l6a_1p8: l6 { + + vreg_l6a_1p8: l6 { /* Touchscreen */ regulator-min-microvolt = <1808000>; regulator-max-microvolt = <1808000>; }; - vreg_l7a_1p8: l7 { + + vreg_l7a_1p8: l7 { /* Wi-Fi + BT */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; - vreg_l8a_1p2: l8 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - }; - vreg_l9a_1p8: l9 { - regulator-min-microvolt = <1808000>; - regulator-max-microvolt = <2960000>; - }; - vreg_l10a_1p8: l10 { - regulator-min-microvolt = <1808000>; - regulator-max-microvolt = <2960000>; - }; - vreg_l11a_1p0: l11 { - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1000000>; - }; - vreg_l12a_1p8: l12 { + + vreg_l12a_1p8: l12 { /* QUSB2 PHY */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; - vreg_l13a_2p95: l13 { - regulator-min-microvolt = <1808000>; - regulator-max-microvolt = <2960000>; - }; - vreg_l14a_1p88: l14 { + + vreg_l14a_1p88: l14 { /* DSI display */ regulator-min-microvolt = <1880000>; regulator-max-microvolt = <1880000>; }; - vreg_l15a_1p8: l15 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vreg_l16a_2p7: l16 { - regulator-min-microvolt = <2704000>; - regulator-max-microvolt = <2704000>; - }; - vreg_l17a_1p3: l17 { + + vreg_l17a_1p3: l17 { /* Wi-Fi + BT */ regulator-min-microvolt = <1304000>; regulator-max-microvolt = <1304000>; }; - vreg_l18a_2p7: l18 { - regulator-min-microvolt = <2704000>; - regulator-max-microvolt = <2704000>; - }; - vreg_l19a_3p0: l19 { - regulator-min-microvolt = <3008000>; - regulator-max-microvolt = <3008000>; - }; - vreg_l20a_2p95: l20 { + + vreg_l20a_2p95: l20 { /* UFS HC */ regulator-min-microvolt = <2960000>; regulator-max-microvolt = <2960000>; regulator-allow-set-load; }; - vreg_l21a_2p95: l21 { - regulator-min-microvolt = <2960000>; - regulator-max-microvolt = <2960000>; - regulator-allow-set-load; - regulator-system-load = <800000>; - }; - vreg_l22a_2p85: l22 { - regulator-min-microvolt = <2864000>; - regulator-max-microvolt = <2864000>; - }; - vreg_l23a_3p3: l23 { - regulator-min-microvolt = <3312000>; - regulator-max-microvolt = <3312000>; - }; - vreg_l24a_3p075: l24 { + + vreg_l24a_3p075: l24 { /* QUSB2 PHY */ regulator-min-microvolt = <3088000>; regulator-max-microvolt = <3088000>; }; - vreg_l25a_3p3: l25 { + + vreg_l25a_3p3: l25 { /* Wi-Fi + BT */ regulator-min-microvolt = <3104000>; regulator-max-microvolt = <3312000>; }; - vreg_l26a_1p2: l26 { + + vreg_l26a_1p2: l26 { /* UFS PHY + HC */ regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-allow-set-load; }; - vreg_l28_3p0: l28 { + + vreg_l28_3p0: l28 { /* Touchscreen */ regulator-min-microvolt = <3008000>; regulator-max-microvolt = <3008000>; }; + vreg_lvs1a_1p8: lvs1 { }; vreg_lvs2a_1p8: lvs2 { }; }; @@ -438,9 +493,140 @@ }; }; +&remoteproc_adsp { + status = "okay"; + + firmware-name = "qcom/msm8998/oneplus/adsp.mbn"; +}; + +&remoteproc_mss { + status = "okay"; + + firmware-name = "qcom/msm8998/oneplus/mba.mbn", "qcom/msm8998/oneplus/modem.mbn"; +}; + +&remoteproc_slpi { + status = "okay"; + + firmware-name = "qcom/msm8998/oneplus/slpi_v2.mbn"; +}; + +&mdss { + status = "okay"; +}; + +&mdss_mdp { + status = "okay"; + + /* It appears CTL_START register always reads back as 0 */ + qcom,ctl-no-start-read-quirk; +}; + +&dsi0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + vdd-supply = <&vreg_l1a_0p875>; + vdda-supply = <&vreg_l2a_1p2>; + + panel: panel@0 { + reg = <0>; + + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + disp-te-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>; + + vddio-supply = <&vreg_l14a_1p88>; // TODO: Could this be moved under dsi0? + + pinctrl-names = "default"; + pinctrl-0 = <&panel_reset_n &disp_en_default &mdp_vsync_n>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; +}; + +&dsi0_phy { + status = "okay"; + vdds-supply = <&vreg_l1a_0p875>; +}; + +&dsi0_out { + remote-endpoint = <&panel_in>; + data-lanes = <0 1 2 3>; +}; + +/* Adreno 540 GPU */ +&gpucc { + status = "okay"; +}; + +&gpu_mem { + compatible = "shared-dma-pool"; +}; + +&adreno_gpu { + status = "okay"; + + zap-shader { + memory-region = <&zap_shader_region>; // gpu_mem? + firmware-name = "qcom/msm8998/oneplus/a540_zap.mbn"; + }; + + /* + * We are lacking support for the GPU regulator. Hence, disable higher + * frequencies for now to prevent the platform from hanging on high + * graphics loads. Perhaps the pm8005_s1 voltage below could be + * adjusted but I'd rather not touch it. + */ + opp-table { + /delete-node/ opp-710000097; + /delete-node/ opp-670000048; + /delete-node/ opp-596000097; + /delete-node/ opp-515000097; + }; +}; + +&adreno_smmu { + status = "okay"; +}; + +/* + * HACK: Shoot GPU voltage high to stabilize Adreno 540 at high frequencies + * until the GPU CPR is brought up. + */ +&pm8005_s1 { + regulator-min-microvolt = <988000>; /* 0,524V -> 0,988V */ + //regulator-max-microvolt = <1100000>; +}; + &tlmm { gpio-reserved-ranges = <0 4>, <81 4>; + disp_en_default: disp-en { + pins = "gpio62"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + panel_reset_n: panel-rst-n { + pins = "gpio94"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + mdp_vsync_n: mdp-vsync-n { + pins = "gpio11"; + function = "mdp_vsync_a"; + drive-strength = <2>; + bias-pull-down; + }; + hall_sensor_default: hall-sensor-default { pins = "gpio124"; function = "gpio"; @@ -462,6 +648,20 @@ drive-strength = <8>; bias-pull-up; }; + + nfc_int_active: nfc_int_active { + pins = "gpio92"; + function = "gpio"; + drive-strength = <6>; + bias-pull-up; + }; + + nfc_enable_active: nfc_enable_active { + pins = "gpio12", "gpio116"; + function = "gpio"; + drive-strength = <6>; + bias-pull-up; + }; }; &ufshc { @@ -503,7 +703,7 @@ }; &wifi { - /* Leave disabled until MSS is functional */ + status = "okay"; vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>; vdd-1.8-xo-supply = <&vreg_l7a_1p8>; vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; diff --git a/arch/arm64/boot/dts/qcom/msm8998-oneplus-dumpling.dts b/arch/arm64/boot/dts/qcom/msm8998-oneplus-dumpling.dts index 5d0dabbaee4e..cec8f0c56b5b 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-oneplus-dumpling.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-oneplus-dumpling.dts @@ -24,3 +24,8 @@ &rmi4_f12 { touchscreen-y-mm = <137>; }; + +/* Display */ +&panel { + compatible = "samsung,s6e3fc1"; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-lilac.dts b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-lilac.dts index caacb7c28402..db254df10958 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-lilac.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-lilac.dts @@ -25,7 +25,16 @@ qcom,soft-start-us = <800>; }; +&wcd9335 { + pinctrl-0 = <&cdc_reset_n &wcd_int_n>; + pinctrl-names = "default"; +}; + &vreg_l22a_2p85 { regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; }; + +&vreg_lvs1a_1p8 { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-maple.dts b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-maple.dts index 978495a8a6b9..7a730ae623b5 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-maple.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-maple.dts @@ -26,6 +26,28 @@ }; }; +&dsi0 { + qcom,dual-dsi-mode; + qcom,master-dsi; +}; + +&dsi1 { + vdd-supply = <&vreg_l1a_0p875>; + vdda-supply = <&vreg_l2a_1p2>; + qcom,dual-dsi-mode; + status = "ok"; +}; + +&dsi1_out { + remote-endpoint = <&panel_in1>; + data-lanes = <0 1 2 3>; +}; + +&dsi1_phy { + vdds-supply = <&vreg_l1a_0p875>; + status = "ok"; +}; + &ibb { regulator-min-microvolt = <5600000>; regulator-max-microvolt = <5600000>; @@ -37,6 +59,32 @@ qcom,soft-start-us = <200>; }; +&panel { + compatible = "sharp,ls055d1sx04"; + + dvdd-supply = <&disp_dvdd_vreg>; + ports { + port@1 { + reg = <1>; + panel_in1: endpoint { + remote-endpoint = <&dsi1_out>; + }; + }; + }; +}; + +&pm8005_gpio { + ear_en_default: ear-en-active { + pins = "gpio1"; + function = "normal"; + bias-disable; + drive-push-pull; + output-high; + power-source = <1>; /* 1.8V */ + qcom,drive-strength = <1>; + }; +}; + &pmi8998_gpio { disp_dvdd_en: disp-dvdd-en-active { pins = "gpio10"; @@ -53,3 +101,17 @@ regulator-min-microvolt = <2704000>; regulator-max-microvolt = <2704000>; }; + + +&pmi8998_wled { + status = "okay"; + + //qcom,auto-string-detection; + qcom,num-strings = <3>; + qcom,enabled-strings = <0 1 2>; +}; + +&wcd9335 { + pinctrl-0 = <&cdc_reset_n &wcd_int_n &ear_en_default>; + pinctrl-names = "default"; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts index 4a1f98a21031..4c55fd7636fb 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts @@ -25,6 +25,11 @@ qcom,soft-start-us = <800>; }; +&wcd9335 { + pinctrl-0 = <&cdc_reset_n &wcd_int_n>; + pinctrl-names = "default"; +}; + &vreg_l18a_2p85 { regulator-min-microvolt = <2850000>; regulator-max-microvolt = <2850000>; diff --git a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi index 47488a1aecae..45a1bf1c27dc 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi @@ -20,9 +20,11 @@ qcom,msm-id = <0x124 0x20000>, <0x124 0x20001>; /* 8998v2, v2.1 */ qcom,board-id = <8 0>; - clocks { - compatible = "simple-bus"; + chosen { + bootargs = "clk_ignore_unused root=/dev/mmcblk0p1"; + }; + clocks { div1_mclk: divclk1 { compatible = "gpio-gate-clock"; pinctrl-0 = <&audio_mclk_pin>; @@ -84,6 +86,15 @@ pinctrl-0 = <&ts_vddio_en>; }; + /* The gpio-vibrator driver enforces requiring a regulator */ + vib_vreg: vib-regulator { + compatible = "regulator-fixed"; + regulator-name = "vib"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; regulator-name = "vph_pwr"; @@ -91,6 +102,14 @@ regulator-boot-on; }; + extcon_usb: extcon-usb { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&tlmm 38 GPIO_ACTIVE_HIGH>; + vbus-gpio = <&tlmm 128 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_extcon_active &usb_vbus_active>; + }; + gpio-keys { compatible = "gpio-keys"; label = "Side buttons"; @@ -184,11 +203,28 @@ vibrator { compatible = "gpio-vibrator"; enable-gpios = <&pmi8998_gpio 5 GPIO_ACTIVE_HIGH>; + vcc-supply = <&vib_vreg>; pinctrl-names = "default"; pinctrl-0 = <&vib_default>; }; }; +&adreno_gpu { + status = "ok"; + + zap-shader { + memory-region = <&zap_shader_region>; + }; +}; + +&adreno_smmu { + status = "ok"; +}; + +&apc_cprh { + status = "ok"; +}; + &blsp1_i2c5 { status = "okay"; clock-frequency = <355000>; @@ -241,10 +277,79 @@ }; }; +&blsp2_i2c1 { + tof-sensor@29 { + compatible = "st,vl53l0x"; + reg = <0x29>; + interrupt-parent = <&tlmm>; + interrupts = <23 IRQ_TYPE_EDGE_FALLING>; + #io-channel-cells = <1>; + label = "back_camera_tof"; + pinctrl-names = "default"; + pinctrl-0 = <&tof_int_n &tof_rst_n>; + }; +}; + &blsp2_uart1 { status = "okay"; }; +&cpufreq_hw { + status = "ok"; +}; + +&dsi0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + vdd-supply = <&vreg_l1a_0p875>; + vdda-supply = <&vreg_l2a_1p2>; + + panel: panel@0 { + reg = <0>; + + backlight = <&pmi8998_wled>; + disp-te-gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; + reset-gpios = <&tlmm 94 GPIO_ACTIVE_HIGH>; + + avdd-supply = <&lab>; + avee-supply = <&ibb>; + vddio-supply = <&vreg_l14a_1p85>; + tavdd-supply = <&vreg_l28_3p0>; + tvddio-supply = <&touch_vddio_vreg>; + + pinctrl-names = "default"; + pinctrl-0 = <&panel_reset_n &mdp_vsync_n>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + panel_in0: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; + }; +}; + +&dsi0_out { + remote-endpoint = <&panel_in0>; + data-lanes = <0 1 2 3>; +}; + +&dsi0_phy { + status = "okay"; + vdds-supply = <&vreg_l1a_0p875>; +}; + +&gpucc { + status = "ok"; +}; + &ibb { regulator-min-microamp = <800000>; regulator-max-microamp = <800000>; @@ -270,6 +375,13 @@ regulator-soft-start; }; +&lpass_q6_smmu { + qcom,bypass-cbndx = /bits/ 8 <11>; + qcom,reset-nodisable-cbs = /bits/ 8 <12>; + + status = "ok"; +}; + &mmcc { status = "ok"; }; @@ -278,19 +390,23 @@ status = "ok"; }; -&pm8005_lsid1 { - pm8005-regulators { - compatible = "qcom,pm8005-regulators"; +&mdss { + status = "okay"; +}; - vdd_s1-supply = <&vph_pwr>; - - /* VDD_GFX supply */ - pm8005_s1: s1 { - regulator-min-microvolt = <524000>; - regulator-max-microvolt = <1088000>; - regulator-enable-ramp-delay = <500>; - regulator-always-on; - }; +&pm8005_regulators { + /* VDD_GFX supply */ + pm8005_s1: s1 { + /* + * HACK: Set enough voltage for max GPU frequency + * and set the regulator always on until the + * GPU Core Power Reduction gets available + */ + regulator-min-microvolt = <988000>; + regulator-max-microvolt = <1088000>; + regulator-enable-ramp-delay = <500>; + /* Hack until we rig up the gpu consumer */ + regulator-always-on; }; }; @@ -324,6 +440,13 @@ function = "func2"; power-source = <0>; }; + + nfc_clk_req_pin: nfc-clk-req-active { + pins = "gpio21"; + function = PMIC_GPIO_FUNC_NORMAL; + input-enable; + power-source = <1>; + }; }; &pmi8998_gpio { @@ -358,6 +481,37 @@ }; }; +&pmi8998_wled { + status = "okay"; + + default-brightness = <800>; + qcom,switching-freq = <800>; + qcom,ovp-millivolt = <29600>; + qcom,current-boost-limit = <970>; + qcom,current-limit-microamp = <25000>; + qcom,num-strings = <2>; + qcom,enabled-strings = <0 1>; +}; + +&q6asmdai { + dai@0 { + reg = <0>; + }; + + dai@1 { + reg = <1>; + }; + + dai@2 { + reg = <2>; + }; + dai@3 { + reg = <3>; +// direction = <2>; +// is-compress-dai; + }; +}; + &qusb2phy { status = "okay"; @@ -365,6 +519,19 @@ vdda-phy-dpdm-supply = <&vreg_l24a_3p075>; }; +&remoteproc_adsp { + firmware-name = "adsp.mdt"; + status = "okay"; +}; + +&remoteproc_mss { + status = "disabled"; +}; + +&remoteproc_slpi { + firmware-name = "slpi.mdt"; +}; + &rpm_requests { pm8998-regulators { compatible = "qcom,rpm-pm8998-regulators"; @@ -401,131 +568,162 @@ regulator-min-microvolt = <1352000>; regulator-max-microvolt = <1352000>; }; + vreg_s4a_1p8: s4 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-system-load = <100000>; regulator-allow-set-load; }; + vreg_s5a_2p04: s5 { regulator-min-microvolt = <1904000>; regulator-max-microvolt = <2032000>; }; + vreg_s7a_1p025: s7 { regulator-min-microvolt = <900000>; regulator-max-microvolt = <1028000>; }; + vreg_l1a_0p875: l1 { regulator-min-microvolt = <880000>; regulator-max-microvolt = <880000>; regulator-system-load = <73400>; regulator-allow-set-load; }; + vreg_l2a_1p2: l2 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-system-load = <12560>; regulator-allow-set-load; }; + vreg_l3a_1p0: l3 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; }; + vreg_l5a_0p8: l5 { regulator-min-microvolt = <800000>; regulator-max-microvolt = <800000>; }; + vreg_l6a_1p8: l6 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + vreg_l7a_1p8: l7 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + vreg_l8a_1p2: l8 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; }; + vreg_l9a_1p8: l9 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; }; + vreg_l10a_1p8: l10 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; }; + vreg_l11a_1p0: l11 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; }; + vreg_l12a_1p8: l12 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + vreg_l13a_2p95: l13 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; regulator-allow-set-load; }; + vreg_l14a_1p85: l14 { regulator-min-microvolt = <1848000>; regulator-max-microvolt = <1856000>; regulator-system-load = <32000>; regulator-allow-set-load; }; + vreg_l15a_1p8: l15 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + vreg_l16a_2p7: l16 { regulator-min-microvolt = <2704000>; regulator-max-microvolt = <2704000>; }; + vreg_l17a_1p3: l17 { regulator-min-microvolt = <1304000>; regulator-max-microvolt = <1304000>; }; - vreg_l18a_2p85: l18 {}; + + vreg_l18a_2p85: l18 { }; + vreg_l19a_2p7: l19 { regulator-min-microvolt = <2696000>; regulator-max-microvolt = <2704000>; }; + vreg_l20a_2p95: l20 { regulator-min-microvolt = <2960000>; regulator-max-microvolt = <2960000>; regulator-system-load = <10000>; regulator-allow-set-load; }; + vreg_l21a_2p95: l21 { regulator-min-microvolt = <2960000>; regulator-max-microvolt = <2960000>; regulator-system-load = <800000>; regulator-allow-set-load; }; + vreg_l22a_2p85: l22 { }; + vreg_l23a_3p3: l23 { regulator-min-microvolt = <3312000>; regulator-max-microvolt = <3312000>; }; + vreg_l24a_3p075: l24 { regulator-min-microvolt = <3088000>; regulator-max-microvolt = <3088000>; }; + vreg_l25a_3p3: l25 { regulator-min-microvolt = <3104000>; regulator-max-microvolt = <3312000>; }; + vreg_l26a_1p2: l26 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-allow-set-load; }; + vreg_l28_3p0: l28 { regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; }; + vreg_lvs1a_1p8: lvs1 { }; + vreg_lvs2a_1p8: lvs2 { }; }; @@ -549,8 +747,373 @@ vqmmc-supply = <&vreg_l13a_2p95>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + pinctrl-0 = <&sdc2_on &sdc2_cd>; + pinctrl-1 = <&sdc2_off &sdc2_cd>; +}; + + /* EAR-EN is NXP NX5L2750C */ + +/* Downstream example +&snd_9335 { + qcom,msm-mbhc-hphl-swh = <1>; + /delete-property/ qcom,hph-en1-gpio; + /delete-property/ qcom,hph-en0-gpio; + /delete-property/ qcom,us-euro-gpios; + qcom,ear-en-gpios = <&pm8005_gpios 1 0>; + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "MIC BIAS2", "ANCRight Headset Mic", + "AMIC3", "MIC BIAS3", + "MIC BIAS3", "ANCLeft Headset Mic", + "DMIC0", "MIC BIAS1", + "MIC BIAS1", "Digital Mic0", + "DMIC3", "MIC BIAS4", + "MIC BIAS4", "Digital Mic3", + "SpkrLeft IN", "SPK1 OUT", + "SpkrRight IN", "SPK2 OUT"; +}; +*/ + +&slimbam { + status = "okay"; +}; + +&slim { + status = "okay"; +}; + +&slim_ngd { + tasha_ifd: tas-ifd { + compatible = "slim217,1a0"; + reg = <0 0>; + }; + + wcd9335: codec@1{ + compatible = "slim217,1a0"; + reg = <1 0>; + + clock-names = "mclk", "slimbus"; + clocks = <&div1_mclk>, + <&rpmcc RPM_SMD_LN_BB_CLK1>; + #clock-cells = <0>; + + interrupt-parent = <&tlmm>; + interrupts = <54 IRQ_TYPE_LEVEL_HIGH>, + <53 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "intr1", "intr2"; + interrupt-controller; + #interrupt-cells = <1>; + + reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + + slim-ifc-dev = <&tasha_ifd>; + + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; + vdd-rx-supply = <&vreg_s4a_1p8>; + vdd-io-supply = <&vreg_s4a_1p8>; + qcom,mbhc-vthreshold = <1700>; + + /* On SoMC Yoshino, HPHL is normally open, GND normally closed */ + qcom,hphl-jack-type-normally-open; + //qcom,gnd-jack-type-normally-open; + + #address-cells = <1>; + #size-cells = <1>; + #sound-dai-cells = <1>; + + swm: swm@c85 { + compatible = "qcom,soundwire-v1.3.0"; + reg = <0xc85 0x40>; + interrupts-extended = <&wcd9335 13>; + + qcom,dout-ports = <6>; + qcom,din-ports = <2>; + qcom,ports-sinterval-low =/bits/ 8 <0x07 0x1F 0x3F 0x7 0x1F 0x3F 0x0F 0x0F>; + qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0C 0x6 0x12 0x0D 0x07 0x0A >; + qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x1F 0x00 0x00 0x1F 0x00 0x00>; + /*downstream is <0xFF 0x00 0x1F 0xFF 0x00 0x1F 0x00 0x00>;*/ + qcom,ports-block-pack-mode = /bits/ 8 <0xFF 0xFF 0x01 0xFF 0xFF 0x01 0xFF 0xFF>; + clocks = <&xo>; + clock-names = "iface"; + #address-cells = <2>; + #size-cells = <0>; + #sound-dai-cells = <1>; + + left_spkr: wsa8810-left { + compatible = "sdw10217201000"; + reg = <0 1>; + powerdown-gpios = <&tlmm 65 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&wsa_leftspk_pwr_n>; + pinctrl-names = "default"; + #thermal-sensor-cells = <0>; + sound-name-prefix = "SpkrRight"; + #sound-dai-cells = <0>; + }; + + right_spkr: wsa8810-right { + compatible = "sdw10217201000"; + powerdown-gpios = <&tlmm 66 GPIO_ACTIVE_HIGH>; + reg = <0 2>; + pinctrl-0 = <&wsa_rightspk_pwr_n>; + pinctrl-names = "default"; + #thermal-sensor-cells = <0>; + sound-name-prefix = "SpkrLeft"; + #sound-dai-cells = <0>; + }; + }; + }; +}; + + +/* NOTES */ +/* + # This is Dragonboard 820C + EnableSequence [ + cset "name='SLIM RX0 MUX' ZERO" + cset "name='SLIM RX1 MUX' ZERO" + cset "name='SLIM RX2 MUX' ZERO" + cset "name='SLIM RX3 MUX' ZERO" + cset "name='SLIM RX4 MUX' ZERO" + cset "name='SLIM RX5 MUX' AIF4_PB" + cset "name='SLIM RX6 MUX' AIF4_PB" + cset "name='SLIM RX7 MUX' ZERO" + cset "name='RX INT1_2 MUX' RX5" + cset "name='RX INT2_2 MUX' RX6" + ## gain to 0dB + cset "name='RX5 Digital Volume' 68" + ## gain to 0dB + cset "name='RX6 Digital Volume' 68" + cset "name='SLIMBUS_6_RX Audio Mixer MultiMedia2' 1" + cset "name='RX INT1 DEM MUX' CLSH_DSM_OUT" + cset "name='RX INT2 DEM MUX' CLSH_DSM_OUT" + ] + + +######### WORKS!!!!!! SHE SPEEEEEAKS!!!!!!! ######### +tinymix set "SLIM RX2 MUX" ZERO +tinymix set "SLIM RX3 MUX" ZERO +tinymix set "SLIM RX4 MUX" ZERO +tinymix set "SLIM RX5 MUX" ZERO +tinymix set "SLIM RX6 MUX" ZERO +tinymix set "SLIM RX7 MUX" ZERO +tinymix set "SLIM RX0 MUX" AIF1_PB +tinymix set "SLIM RX1 MUX" AIF1_PB +tinymix set "RX INT1_2 MUX" RX0 +tinymix set "RX INT2_2 MUX" RX1 +tinymix set "RX INT1_1 MIX1 INP0" RX0 +tinymix set "RX INT2_1 MIX1 INP0" RX1 +tinymix set "SLIMBUS_0_RX Audio Mixer MultiMedia1" 1 +tinymix set "RX INT1 DEM MUX" CLSH_DSM_OUT +tinymix set "RX INT2 DEM MUX" CLSH_DSM_OUT +tinymix set "SLIM TX0 MUX" DEC0 +tinymix set "AIF1_CAP Mixer SLIM TX0" 1 + +tinymix set "RX INT2_1 MIX1 INP0" RX1 +tinymix set "RX INT1_1 MIX1 INP0" RX0 +tinymix set "RX INT1_1 MIX1 INP0" RX2 +tinymix set "RX INT1_1 MIX1 INP0" RX0 +tinymix set "RX INT1_1 MIX1 INP0" RX2 +tinymix set "RX INT2_1 MIX1 INP0" RX2 +tinymix set "RX INT2_1 MIX1 INP0" RX1 +tinymix set "RX INT1_1 MIX1 INP0" RX0 +tinymix set "RX INT0_1 MIX1 INP0" RX0 +tinymix set "RX INT0_1 MIX1 INP0" RX1 +tinymix set "RX INT0_1 MIX1 INP0" RX2 +tinymix set "RX INT0_1 MIX1 INP0" RX0 +tinymix set "RX INT3_1 MIX1 INP0" RX0 +tinymix set "RX INT4_1 MIX1 INP0" RX0 +tinymix set "RX INT5_1 MIX1 INP0" RX0 +tinymix set "RX INT6_1 MIX1 INP0" RX1 +tinymix set "RX INT7_1 MIX1 INP0" RX1 +tinymix set "RX INT7_1 MIX1 INP0" RX1 +tinymix set "RX INT8_1 MIX1 INP0" RX1 +tinymix set "RX INT0_1 MIX1 INP1" RX0 +tinymix set "RX INT0_1 MIX1 INP1" RX2 +tinymix set "RX INT0_1 MIX1 INP1" RX0 +tinymix set "RX INT1_1 MIX1 INP1" RX0 +tinymix set "RX INT2_1 MIX1 INP1" RX0 +tinymix set "RX INT3_1 MIX1 INP1" RX0 +tinymix set "RX INT4_1 MIX1 INP1" RX0 +tinymix set "RX INT5_1 MIX1 INP1" RX0 +tinymix set "RX INT6_1 MIX1 INP1" RX0 +tinymix set "RX INT7_1 MIX1 INP1" RX0 +tinymix set "RX INT8_1 MIX1 INP1" RX0 +tinymix set "RX INT0_1 MIX1 INP2" RX1 +tinymix set "RX INT1_1 MIX1 INP2" RX1 +tinymix set "RX INT2_1 MIX1 INP2" RX1 +tinymix set "RX INT3_1 MIX1 INP2" RX1 +tinymix set "RX INT4_1 MIX1 INP2" RX1 +tinymix set "RX INT5_1 MIX1 INP2" RX1 +tinymix set "RX INT6_1 MIX1 INP2" RX1 +tinymix set "RX INT7_1 MIX1 INP2" RX1 +tinymix set "RX INT8_1 MIX1 INP2" RX1 +tinymix set "RX INT8_1 MIX1 INP2" RX0 +tinymix set "RX INT7_1 MIX1 INP2" RX0 +tinymix set "RX INT6_1 MIX1 INP2" RX0 + +tinymix set "RX0 Digital Volume" 80 +tinymix set "RX1 Digital Volume" 80 +tinymix set "RX2 Digital Volume" 80 + +*/ + +&sound { + compatible = "qcom,msm8998-sndcard"; + model = "Sony-Xperia-Yoshino"; + + /* Audio routing including WSA amp speakers */ +/* audio-routing = "RX_BIAS", "MCLK", + "AMIC2", "MIC BIAS2", + "AMIC3", "MIC BIAS3", + "DMIC0", "MIC BIAS1", + "DMIC4", "MIC BIAS4", + "SpkrLeft IN", "SPK1 OUT", + "SpkrRight IN", "SPK2 OUT", + "MM_DL1", "MultiMedia1 Playback", + "MM_DL2", "MultiMedia2 Playback", + "MultiMedia3 Capture", "MM_UL3"; +*/ + + /* Basic routing, 3.5mm jack only */ + audio-routing = "RX_BIAS", "MCLK", + "AMIC2", "MIC BIAS2", + "AMIC3", "MIC BIAS3", + "DMIC0", "MIC BIAS1", + "DMIC4", "MIC BIAS4", + "MM_DL1", "MultiMedia1 Playback", + "MM_DL2", "MultiMedia2 Playback", + "MultiMedia3 Capture", "MM_UL3"; + +/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +*/ + + mm1-dai-link { + /* Deep Buffer playback for SLIM{0,7}, BT, USBAUDIO, AFE, DP, HDMI */ + link-name = "MultiMedia1"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; + }; + }; + + mm2-dai-link { + /* Multichannel playback for HDMI and DP */ + link-name = "MultiMedia2"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>; + }; + }; + + mm3-dai-link { + /* Ultra Low Latency playback for SLIM0, HDMI, and DP */ + link-name = "MultiMedia3"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; + }; + }; + + slim-dai-link { + link-name = "SLIM Playback"; + cpu { + sound-dai = <&q6afedai SLIMBUS_0_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + /* Support only sound through 3.5mm for now: soundwire is currently unavailable */ + //sound-dai = <&left_spkr>, <&right_spkr>, <&swm 0>, <&wcd9335 0>; + sound-dai = <&wcd9335 0>; + }; + }; + + slimcap-dai-link { + link-name = "SLIM Capture"; + cpu { + sound-dai = <&q6afedai SLIMBUS_0_TX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&wcd9335 1>; + }; + }; }; &tlmm { @@ -606,6 +1169,14 @@ drive-strength = <2>; }; + tof_int_n: tof-int-n { + pins = "gpio22"; + function = "gpio"; + bias-pull-up; + drive-strength = <2>; + input-enable; + }; + cam1_vdig_default: cam1-vdig-default { pins = "gpio25"; function = "gpio"; @@ -613,6 +1184,81 @@ drive-strength = <2>; }; + tof_rst_n: tof-rst-n { + pins = "gpio27"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + output-low; + }; + + cam1_rst_default: cam1-rst-n { + pins = "gpio28"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + }; + + cam0_rst_default: cam0-rst-n { + pins = "gpio30"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + }; + + wcd_int_n: wcd-int-n { + pins = "gpio54"; + function = "gpio"; + bias-pull-down; + drive-strength = <2>; + input-enable; + }; + + cdc_reset_n: cdc-reset-n { + pins = "gpio64"; + function = "gpio"; + bias-pull-down; + drive-strength = <16>; + output-high; + }; + + wsa_leftspk_pwr_n: wsa-leftspk-pwr-n { + pins = "gpio65"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + output-low; + }; + + wsa_rightspk_pwr_n: wsa-rightspk-pwr-n { + pins = "gpio66"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + output-low; + }; + + ts_reset_n: ts-reset-n { + pins = "gpio89"; + function = "gpio"; + bias-pull-up; + drive-strength = <8>; + }; + + panel_reset_n: panel-rst-n { + pins = "gpio94"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + }; + + usb_extcon_active: usb-extcon-active { + pins = "gpio38"; + function = "gpio"; + bias-disable; + drive-strength = <16>; + }; + hall_sensor0_default: acc-cover-open { pins = "gpio124"; function = "gpio"; @@ -628,6 +1274,14 @@ bias-pull-up; }; + usb_vbus_active: usb-vbus-active { + pins = "gpio128"; + function = "gpio"; + bias-disable; + drive-strength = <2>; + output-low; + }; + ts_vddio_en: ts-vddio-en-default { pins = "gpio133"; function = "gpio"; @@ -658,6 +1312,7 @@ &usb3_dwc3 { /* Force to peripheral until we have Type-C hooked up */ dr_mode = "peripheral"; + extcon = <&extcon_usb>; }; &usb3phy { diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi index 2fda21e810c9..b910306aede0 100644 --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -6,9 +6,20 @@ #include #include #include +#include #include +#include #include +/* Macro for CPR-Hardened OPP entries - Example phandle: cprh_opp0 */ +#define CPRH_OPP_ENTRY(lvl, _fuselevel, _oadj, _cadj) \ + cprh_opp##lvl##: opp-##lvl { \ + opp-level = ; \ + qcom,opp-fuse-level = <_fuselevel>; \ + qcom,opp-oloop-vadj = <_oadj>; \ + qcom,opp-cloop-vadj = <_cadj>; \ + } + / { interrupt-parent = <&intc>; @@ -135,8 +146,13 @@ reg = <0x0 0x0>; enable-method = "psci"; capacity-dmips-mhz = <1024>; + clocks = <&xo>; cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; next-level-cache = <&L2_0>; + operating-points-v2 = <&cpu_silver_opp_table>; + power-domains = <&apc_cprh 0>; + power-domain-names = "cprh"; + qcom,freq-domain = <&cpufreq_hw 0>; L2_0: l2-cache { compatible = "cache"; cache-level = <2>; @@ -149,8 +165,13 @@ reg = <0x0 0x1>; enable-method = "psci"; capacity-dmips-mhz = <1024>; + clocks = <&xo>; cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; next-level-cache = <&L2_0>; + operating-points-v2 = <&cpu_silver_opp_table>; + power-domains = <&apc_cprh 0>; + power-domain-names = "cprh"; + qcom,freq-domain = <&cpufreq_hw 0>; }; CPU2: cpu@2 { @@ -159,8 +180,13 @@ reg = <0x0 0x2>; enable-method = "psci"; capacity-dmips-mhz = <1024>; + clocks = <&xo>; cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; next-level-cache = <&L2_0>; + operating-points-v2 = <&cpu_silver_opp_table>; + power-domains = <&apc_cprh 0>; + power-domain-names = "cprh"; + qcom,freq-domain = <&cpufreq_hw 0>; }; CPU3: cpu@3 { @@ -169,8 +195,13 @@ reg = <0x0 0x3>; enable-method = "psci"; capacity-dmips-mhz = <1024>; + clocks = <&xo>; cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; next-level-cache = <&L2_0>; + operating-points-v2 = <&cpu_silver_opp_table>; + power-domains = <&apc_cprh 0>; + power-domain-names = "cprh"; + qcom,freq-domain = <&cpufreq_hw 0>; }; CPU4: cpu@100 { @@ -179,8 +210,13 @@ reg = <0x0 0x100>; enable-method = "psci"; capacity-dmips-mhz = <1536>; + clocks = <&xo>; cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; next-level-cache = <&L2_1>; + operating-points-v2 = <&cpu_gold_opp_table>; + power-domains = <&apc_cprh 1>; + power-domain-names = "cprh"; + qcom,freq-domain = <&cpufreq_hw 1>; L2_1: l2-cache { compatible = "cache"; cache-level = <2>; @@ -193,8 +229,13 @@ reg = <0x0 0x101>; enable-method = "psci"; capacity-dmips-mhz = <1536>; + clocks = <&xo>; cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; next-level-cache = <&L2_1>; + operating-points-v2 = <&cpu_gold_opp_table>; + power-domains = <&apc_cprh 1>; + power-domain-names = "cprh"; + qcom,freq-domain = <&cpufreq_hw 1>; }; CPU6: cpu@102 { @@ -203,8 +244,13 @@ reg = <0x0 0x102>; enable-method = "psci"; capacity-dmips-mhz = <1536>; + clocks = <&xo>; cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; next-level-cache = <&L2_1>; + operating-points-v2 = <&cpu_gold_opp_table>; + power-domains = <&apc_cprh 1>; + power-domain-names = "cprh"; + qcom,freq-domain = <&cpufreq_hw 1>; }; CPU7: cpu@103 { @@ -213,8 +259,13 @@ reg = <0x0 0x103>; enable-method = "psci"; capacity-dmips-mhz = <1536>; + clocks = <&xo>; cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; next-level-cache = <&L2_1>; + operating-points-v2 = <&cpu_gold_opp_table>; + power-domains = <&apc_cprh 1>; + power-domain-names = "cprh"; + qcom,freq-domain = <&cpufreq_hw 1>; }; cpu-map { @@ -302,6 +353,378 @@ }; }; + cpu_gold_opp_table: cpu-gold-opp-table { + compatible = "operating-points-v2"; + opp-shared; + + opp-2361600000 { + opp-hz = /bits/ 64 <2361600000>; + required-opps = <&cprh_opp30>; + qcom,pll-override = <0x0a620062>; + qcom,spare-data = <3>; + }; + opp-2342400000 { + opp-hz = /bits/ 64 <2342400000>; + required-opps = <&cprh_opp29>; + qcom,pll-override = <0x0a620062>; + qcom,spare-data = <3>; + }; + opp-2323200000 { + opp-hz = /bits/ 64 <2323200000>; + required-opps = <&cprh_opp28>; + qcom,pll-override = <0x0a610061>; + qcom,spare-data = <3>; + }; + opp-2265600000 { + opp-hz = /bits/ 64 <2265600000>; + required-opps = <&cprh_opp27>; + qcom,pll-override = <0x0a5e005e>; + qcom,spare-data = <3>; + }; + opp-2208000000 { + opp-hz = /bits/ 64 <2208000000>; + required-opps = <&cprh_opp26>; + qcom,pll-override = <0x0a5c005c>; + qcom,spare-data = <3>; + }; + opp-2112000000 { + opp-hz = /bits/ 64 <2112000000>; + required-opps = <&cprh_opp25>; + qcom,pll-override = <0x0a580058>; + qcom,spare-data = <3>; + }; + opp-2035200000 { + opp-hz = /bits/ 64 <2035200000>; + required-opps = <&cprh_opp24>; + qcom,pll-override = <0x09550055>; + qcom,spare-data = <3>; + }; + opp-1958400000 { + opp-hz = /bits/ 64 <1958400000>; + required-opps = <&cprh_opp23>; + qcom,pll-override = <0x09520052>; + qcom,spare-data = <2>; + }; + opp-1881600000 { + opp-hz = /bits/ 64 <1881600000>; + required-opps = <&cprh_opp22>; + qcom,pll-override = <0x094e004e>; + qcom,spare-data = <2>; + }; + opp-1804800000 { + opp-hz = /bits/ 64 <1804800000>; + required-opps = <&cprh_opp21>; + qcom,pll-override = <0x084b004b>; + qcom,spare-data = <2>; + }; + opp-1728000000 { + opp-hz = /bits/ 64 <1728000000>; + required-opps = <&cprh_opp20>; + qcom,pll-override = <0x08480048>; + qcom,spare-data = <2>; + }; + opp-1651200000 { + opp-hz = /bits/ 64 <1651200000>; + required-opps = <&cprh_opp19>; + qcom,pll-override = <0x07450045>; + qcom,spare-data = <2>; + }; + opp-1574400000 { + opp-hz = /bits/ 64 <1574400000>; + required-opps = <&cprh_opp18>; + qcom,pll-override = <0x07420042>; + qcom,spare-data = <2>; + }; + opp-1497600000 { + opp-hz = /bits/ 64 <1497600000>; + required-opps = <&cprh_opp17>; + qcom,pll-override = <0x073e003e>; + qcom,spare-data = <2>; + }; + opp-1420800000 { + opp-hz = /bits/ 64 <1420800000>; + required-opps = <&cprh_opp16>; + qcom,pll-override = <0x063b003b>; + qcom,spare-data = <2>; + }; + opp-1344000000 { + opp-hz = /bits/ 64 <1344000000>; + required-opps = <&cprh_opp15>; + qcom,pll-override = <0x06380038>; + qcom,spare-data = <2>; + }; + + opp-1267200000 { + opp-hz = /bits/ 64 <1267200000>; + required-opps = <&cprh_opp14>; + qcom,pll-override = <0x06350035>; + qcom,spare-data = <2>; + }; + opp-1190400000 { + opp-hz = /bits/ 64 <1190400000>; + required-opps = <&cprh_opp13>; + qcom,pll-override = <0x05320032>; + qcom,spare-data = <2>; + }; + opp-1132800000 { + opp-hz = /bits/ 64 <1132800000>; + required-opps = <&cprh_opp12>; + qcom,pll-override = <0x052f002f>; + qcom,spare-data = <1>; + }; + opp-1056000000 { + opp-hz = /bits/ 64 <1056000000>; + required-opps = <&cprh_opp11>; + qcom,pll-override = <0x052c002c>; + qcom,spare-data = <1>; + }; + opp-979200000 { + opp-hz = /bits/ 64 <979200000>; + required-opps = <&cprh_opp10>; + qcom,pll-override = <0x4290029>; + qcom,spare-data = <1>; + }; + opp-902400000 { + opp-hz = /bits/ 64 <902400000>; + required-opps = <&cprh_opp9>; + qcom,pll-override = <0x4260026>; + qcom,spare-data = <1>; + }; + opp-806400000 { + opp-hz = /bits/ 64 <806400000>; + required-opps = <&cprh_opp8>; + qcom,pll-override = <0x3200022>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-729600000 { + opp-hz = /bits/ 64 <729600000>; + required-opps = <&cprh_opp7>; + qcom,pll-override = <0x3200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-652800000 { + opp-hz = /bits/ 64 <652800000>; + required-opps = <&cprh_opp6>; + qcom,pll-override = <0x3200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-576000000 { + opp-hz = /bits/ 64 <576000000>; + required-opps = <&cprh_opp5>; + qcom,pll-override = <0x2200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-499200000 { + opp-hz = /bits/ 64 <499200000>; + required-opps = <&cprh_opp4>; + qcom,pll-override = <0x2200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-422400000 { + opp-hz = /bits/ 64 <422400000>; + required-opps = <&cprh_opp3>; + qcom,pll-override = <0x2200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-345600000 { + opp-hz = /bits/ 64 <345600000>; + required-opps = <&cprh_opp2>; + qcom,pll-override = <0x1200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&cprh_opp1>; + qcom,pll-override = <0x1200020>; + qcom,spare-data = <1>; + }; + }; + + cpu_silver_opp_table: cpu-silver-opp-table { + compatible = "operating-points-v2"; + opp-shared; + + opp-1900800000 { + opp-hz = /bits/ 64 <1900800000>; + required-opps = <&cprh_opp22>; + qcom,pll-override = <0x094f004f>; + qcom,spare-data = <3>; + }; + opp-1824000000 { + opp-hz = /bits/ 64 <1824000000>; + required-opps = <&cprh_opp21>; + qcom,pll-override = <0x084c004c>; + qcom,spare-data = <3>; + }; + opp-1747200000 { + opp-hz = /bits/ 64 <1747200000>; + required-opps = <&cprh_opp20>; + qcom,pll-override = <0x08490049>; + qcom,spare-data = <2>; + }; + opp-1670400000 { + opp-hz = /bits/ 64 <1670400000>; + required-opps = <&cprh_opp19>; + qcom,pll-override = <0x08460046>; + qcom,spare-data = <2>; + }; + opp-1555200000 { + opp-hz = /bits/ 64 <1555200000>; + required-opps = <&cprh_opp18>; + qcom,pll-override = <0x07410041>; + qcom,spare-data = <2>; + }; + opp-1478400000 { + opp-hz = /bits/ 64 <1478400000>; + required-opps = <&cprh_opp17>; + qcom,pll-override = <0x073e003e>; + qcom,spare-data = <2>; + }; + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; + required-opps = <&cprh_opp16>; + qcom,pll-override = <0x063a003a>; + qcom,spare-data = <2>; + }; + opp-1324800000 { + opp-hz = /bits/ 64 <1324800000>; + required-opps = <&cprh_opp15>; + qcom,pll-override = <0x06370037>; + qcom,spare-data = <2>; + }; + opp-1248000000 { + opp-hz = /bits/ 64 <1248000000>; + required-opps = <&cprh_opp14>; + qcom,pll-override = <0x05340034>; + qcom,spare-data = <2>; + }; + opp-1171200000 { + opp-hz = /bits/ 64 <1171200000>; + required-opps = <&cprh_opp13>; + qcom,pll-override = <0x05310031>; + qcom,spare-data = <2>; + }; + opp-1094400000 { + opp-hz = /bits/ 64 <1094400000>; + required-opps = <&cprh_opp12>; + qcom,pll-override = <0x052e002e>; + qcom,spare-data = <2>; + }; + opp-1036800000 { + opp-hz = /bits/ 64 <1036800000>; + required-opps = <&cprh_opp11>; + qcom,pll-override = <0x042b002b>; + qcom,spare-data = <1>; + }; + opp-960000000 { + opp-hz = /bits/ 64 <960000000>; + required-opps = <&cprh_opp10>; + qcom,pll-override = <0x4280028>; + qcom,spare-data = <1>; + }; + opp-883200000 { + opp-hz = /bits/ 64 <883200000>; + required-opps = <&cprh_opp9>; + qcom,pll-override = <0x4250025>; + qcom,spare-data = <1>; + }; + opp-825600000 { + opp-hz = /bits/ 64 <825600000>; + required-opps = <&cprh_opp8>; + qcom,pll-override = <0x3200022>; + qcom,spare-data = <1>; + }; + opp-748800000 { + opp-hz = /bits/ 64 <748800000>; + required-opps = <&cprh_opp7>; + qcom,pll-override = <0x3200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-672000000 { + opp-hz = /bits/ 64 <672000000>; + required-opps = <&cprh_opp6>; + qcom,pll-override = <0x3200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-595200000 { + opp-hz = /bits/ 64 <595200000>; + required-opps = <&cprh_opp5>; + qcom,pll-override = <0x2200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-518400000 { + opp-hz = /bits/ 64 <518400000>; + required-opps = <&cprh_opp4>; + qcom,pll-override = <0x2200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-441600000 { + opp-hz = /bits/ 64 <441600000>; + required-opps = <&cprh_opp3>; + qcom,pll-override = <0x2200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-364800000 { + opp-hz = /bits/ 64 <364800000>; + required-opps = <&cprh_opp2>; + qcom,pll-override = <0x1200020>; + qcom,pll-div = <1>; + qcom,spare-data = <1>; + }; + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&cprh_opp1>; + qcom,pll-override = <0x1200020>; + }; + }; + + cprh_opp_table: cpr-opp-table { + compatible = "operating-points-v2-qcom-level"; + + CPRH_OPP_ENTRY(1, 1, 0, 0); + CPRH_OPP_ENTRY(2, 1, 0, 0); + CPRH_OPP_ENTRY(3, 1, 0, 0); + CPRH_OPP_ENTRY(4, 1, 0, 0); + CPRH_OPP_ENTRY(5, 1, 0, 0); + CPRH_OPP_ENTRY(6, 1, 0, 0); + CPRH_OPP_ENTRY(7, 1, 0, 0); + CPRH_OPP_ENTRY(8, 1, 0, 0); + CPRH_OPP_ENTRY(9, 2, 0, 0); + CPRH_OPP_ENTRY(10, 2, 0, 0); + CPRH_OPP_ENTRY(11, 2, 0, 0); + CPRH_OPP_ENTRY(12, 3 2, (-12000) (-8000), (-10000) (-10000)); + CPRH_OPP_ENTRY(13, 3, (-16000) (-16000), (-11000) (-10000)); + CPRH_OPP_ENTRY(14, 3, (-16000) (-12000), (-12000) (-11000)); + CPRH_OPP_ENTRY(15, 3, (-12000) (-16000), (-13000) (-12000)); + CPRH_OPP_ENTRY(16, 3, (-12000) (-16000), (-14000) (-12000)); + CPRH_OPP_ENTRY(17, 3, (-16000) (-12000), (-14000) (-13000)); + CPRH_OPP_ENTRY(18, 3, (-16000) (-16000), (-15000) (-14000)); + CPRH_OPP_ENTRY(19, 4 3, (-20000) (-16000), (-21000) (-14000)); + CPRH_OPP_ENTRY(20, 4 3, (-24000) (-16000), (-24000) (-15000)); + CPRH_OPP_ENTRY(21, 4, (-28000) (-24000), (-26000) (-16000)); + CPRH_OPP_ENTRY(22, 4, (-28000) (-16000), (-28000) (-16000)); + CPRH_OPP_ENTRY(23, 4, 0 (-20000), 0 (-17000)); + CPRH_OPP_ENTRY(24, 4, 0 (-16000), 0 (-15000)); + CPRH_OPP_ENTRY(25, 4, 0 (-12000), 0 (-14000)); + CPRH_OPP_ENTRY(26, 4, 0 (-28000), 0 (-27000)); + CPRH_OPP_ENTRY(27, 4, 0 (-28000), 0 (-27000)); + CPRH_OPP_ENTRY(28, 4, 0 (-28000), 0 (-28000)); + CPRH_OPP_ENTRY(29, 4, 0 (-28000), 0 (-28000)); + CPRH_OPP_ENTRY(30, 4, 0 (-28000), 0 (-28000)); + }; + firmware { scm { compatible = "qcom,scm-msm8998", "qcom,scm"; @@ -435,6 +858,17 @@ interrupt-controller; #interrupt-cells = <2>; }; + + ipa_smp2p_out: ipa-ap-to-modem { + qcom,entry-name = "ipa"; + #qcom,smem-state-cells = <1>; + }; + + ipa_smp2p_in: ipa-modem-to-ap { + qcom,entry-name = "ipa"; + interrupt-controller; + #interrupt-cells = <2>; + }; }; smp2p-slpi { @@ -457,6 +891,9 @@ }; }; + sound: sound { + }; + thermal-zones { cpu0-thermal { polling-delay-passive = <250>; @@ -824,7 +1261,7 @@ qfprom: qfprom@784000 { compatible = "qcom,qfprom"; - reg = <0x00784000 0x621c>; + reg = <0x00784000 0x221c>; #address-cells = <1>; #size-cells = <1>; @@ -832,6 +1269,195 @@ reg = <0x23a 0x1>; bits = <0 4>; }; + + cpr_efuse_speedbin: speedbin@133 { + reg = <0x133 0x2>; + bits = <5 3>; + }; + + cpr_fuse_revision: cpr_fusing_rev@13e { + reg = <0x13E 0x1>; + bits = <3 3>; + }; + + /* CPR Ring Oscillator: Power Cluster */ + cpr_ro_sel0_pwrcl: rosel0_pwrcl@219 { + reg = <0x219 0x2>; + bits = <4 4>; + }; + + cpr_ro_sel1_pwrcl: rosel1_pwrcl@219 { + reg = <0x219 0x1>; + bits = <0 4>; + }; + + cpr_ro_sel2_pwrcl: rosel2_pwrcl@218 { + reg = <0x218 0x2>; + bits = <4 4>; + }; + + cpr_ro_sel3_pwrcl: rosel3_pwrcl@218 { + reg = <0x218 0x1>; + bits = <0 4>; + }; + + /* CPR Init Voltage: Power Cluster */ + cpr_init_voltage0_pwrcl: ivolt0_pwrcl@21c { + reg = <0x21C 0x2>; + bits = <2 6>; + }; + + cpr_init_voltage1_pwrcl: ivolt1_pwrcl@21b { + reg = <0x21B 0x2>; + bits = <4 6>; + }; + + cpr_init_voltage2_pwrcl: ivolt2_pwrcl@21a { + reg = <0x21A 0x2>; + bits = <6 6>; + }; + + cpr_init_voltage3_pwrcl: ivolt3_pwrcl@21a { + reg = <0x21A 0x1>; + bits = <0 6>; + }; + + /* CPR Target Quotients: Power Cluster */ + cpr_quot0_pwrcl: quot0_pwrcl@222 { + reg = <0x222 0x3>; + bits = <2 12>; + }; + + cpr_quot1_pwrcl: quot1_pwrcl@220 { + reg = <0x220 0x3>; + bits = <6 12>; + }; + + cpr_quot2_pwrcl: quot2_pwrcl@21f { + reg = <0x21F 0x2>; + bits = <2 11>; + }; + + cpr_quot3_pwrcl: quot3_pwrcl@21d { + reg = <0x21D 0x3>; + bits = <6 12>; + }; + + /* CPR Quotient Offsets: Power Cluster */ + cpr_quot_offset1_pwrcl: qoff1_pwrcl@227 { + reg = <0x227 0x2>; + bits = <7 6>; + }; + + cpr_quot_offset2_pwrcl: qoff2_pwrcl@227 { + reg = <0x227 0x1>; + bits = <0 7>; + }; + + cpr_quot_offset3_pwrcl: qoff3_pwrcl@226 { + reg = <0x226 0x2>; + bits = <1 7>; + }; + + /* CPR Aging Quotient Offsets: Power Cluster */ + cpr_aging_quot_off_pwrcl: qoff_aging_pwrcl@228 { + reg = <0x228 0x2>; + bits = <6 8>; + }; + + /* CPR Ring Oscillator: Performance Cluster */ + cpr_ro_sel0_perfcl: rosel0_perfcl@22b { + reg = <0x22B 0x1>; + bits = <2 4>; + }; + + cpr_ro_sel1_perfcl: rosel1_perfcl@22a { + reg = <0x22A 0x2>; + bits = <6 4>; + }; + + cpr_ro_sel2_perfcl: rosel2_perfcl@22a { + reg = <0x22A 0x1>; + bits = <2 4>; + }; + + cpr_ro_sel3_perfcl: rosel3_perfcl@229 { + reg = <0x229 0x2>; + bits = <6 4>; + }; + + /* CPR Init Voltage: Performance Cluster */ + cpr_init_voltage0_perfcl: ivolt0_perfcl@22e { + reg = <0x22E 0x1>; + bits = <0 6>; + }; + + cpr_init_voltage1_perfcl: ivolt1_perfcl@22d { + reg = <0x22D 0x2>; + bits = <2 6>; + }; + + cpr_init_voltage2_perfcl: ivolt2_perfcl@22c { + reg = <0x22C 0x2>; + bits = <4 6>; + }; + + cpr_init_voltage3_perfcl: ivolt3_perfcl@22b { + reg = <0x22B 0x2>; + bits = <6 6>; + }; + + /* CPR Target Quotients: Performance Cluster */ + cpr_quot0_perfcl: quot0_perfcl@234 { + reg = <0x234 0x2>; + bits = <0 12>; + }; + + cpr_quot1_perfcl: quot1_perfcl@232 { + reg = <0x232 0x2>; + bits = <4 12>; + }; + + cpr_quot2_perfcl: quot2_perfcl@231 { + reg = <0x231 0x2>; + bits = <0 12>; + }; + + cpr_quot3_perfcl: quot3_perfcl@22f { + reg = <0x22F 0x2>; + bits = <4 11>; + }; + + /* CPR Quotient Offsets: Performance Cluster */ + cpr_quot_offset1_perfcl: qoff1_perfcl@239 { + reg = <0x239 0x2>; + bits = <5 3>; + }; + + cpr_quot_offset2_perfcl: qoff2_perfcl@238 { + reg = <0x238 0x2>; + bits = <6 7>; + }; + + cpr_quot_offset3_perfcl: qoff3_perfcl@237 { + reg = <0x237 0x2>; + bits = <7 7>; + }; + + /* CPR Aging Quotient Offsets: Performance Cluster */ + cpr_aging_quot_off_perfcl: qoff_aging_perfcl@23b { + reg = <0x23b 0x2>; + bits = <1 8>; + }; + }; + + bimc: interconnect@1008000 { + compatible = "qcom,msm8998-bimc"; + reg = <0x01008000 0x78000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_BIMC_CLK>, + <&rpmcc RPM_SMD_BIMC_A_CLK>; }; tsens0: thermal@10ab000 { @@ -856,6 +1482,33 @@ #thermal-sensor-cells = <1>; }; + cnoc: interconnect@1500000 { + compatible = "qcom,msm8998-cnoc"; + reg = <0x01500000 0x10000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_CNOC_CLK>, + <&rpmcc RPM_SMD_CNOC_A_CLK>; + }; + + snoc: interconnect@1625000 { + compatible = "qcom,msm8998-snoc"; + reg = <0x01625000 0x6100>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_SNOC_CLK>, + <&rpmcc RPM_SMD_SNOC_A_CLK>; + }; + + a1noc: interconnect@1669000 { + compatible = "qcom,msm8998-a1noc"; + reg = <0x01669000 0x5020>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_AGGR1_NOC_CLK>, + <&rpmcc RPM_SMD_AGGR1_NOC_A_CLK>; + }; + anoc1_smmu: iommu@1680000 { compatible = "qcom,msm8998-smmu-v2", "qcom,smmu-v2"; reg = <0x01680000 0x10000>; @@ -890,6 +1543,25 @@ ; }; + a2noc: interconnect@1705000 { + compatible = "qcom,msm8998-a2noc"; + reg = <0x01705000 0xa090>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_AGGR2_NOC_CLK>, + <&rpmcc RPM_SMD_AGGR2_NOC_A_CLK>; + }; + + mnoc: interconnect@1744000 { + compatible = "qcom,msm8998-mnoc"; + reg = <0x01744000 0xb010>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a", "iface"; + clocks = <&rpmcc RPM_SMD_MMAXI_CLK>, + <&rpmcc RPM_SMD_MMAXI_A_CLK>, + <&mmcc AHB_CLK_SRC>; + }; + pcie0: pci@1c00000 { compatible = "qcom,pcie-msm8996"; reg = <0x01c00000 0x2000>, @@ -1032,6 +1704,50 @@ }; }; + ipa: ipa@1e40000 { + compatible = "qcom,msm8998-ipa"; + + iommus = <&anoc2_smmu 0x18e0 0x0>, + <&anoc2_smmu 0x18e2 0x0>; + reg = <0x1e40000 0x7000>, + <0x1e47000 0x2000>, + <0x1e04000 0x2c000>; + reg-names = "ipa-reg", + "ipa-shared", + "gsi"; + + interrupts-extended = <&intc GIC_SPI 333 IRQ_TYPE_EDGE_RISING>, + <&intc GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>, + <&ipa_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&ipa_smp2p_in 1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "ipa", + "gsi", + "ipa-clock-query", + "ipa-setup-ready"; + + clocks = <&rpmcc RPM_SMD_IPA_CLK>; + clock-names = "core"; + +/* Elder's proposed interconnects: + <&aggre2_noc MASTER_IPA 0 &mem_noc SLAVE_EBI1 0>, + <&aggre2_noc MASTER_IPA 0 &system_noc SLAVE_IMEM 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_IPA_CFG 0> +*/ + interconnects = <&a2noc MASTER_IPA &bimc SLAVE_EBI>, + <&a2noc MASTER_IPA &snoc SLAVE_IMEM>, + <&gnoc MASTER_APSS_PROC &cnoc SLAVE_IPA>; + interconnect-names = "memory", + "imem", + "config"; + + qcom,smem-states = <&ipa_smp2p_out 0>, + <&ipa_smp2p_out 1>; + qcom,smem-state-names = "ipa-clock-enabled-valid", + "ipa-clock-enabled"; + + status = "disabled"; + }; + tcsr_mutex_regs: syscon@1f40000 { compatible = "syscon"; reg = <0x01f40000 0x40000>; @@ -1042,85 +1758,142 @@ reg = <0x03400000 0xc00000>; interrupts = ; gpio-controller; - #gpio-cells = <0x2>; + #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <0x2>; + #interrupt-cells = <2>; - sdc2_clk_on: sdc2_clk_on { - config { + sdc2_on: sdc2-on { + clk { pins = "sdc2_clk"; - bias-disable; drive-strength = <16>; - }; - }; - - sdc2_clk_off: sdc2_clk_off { - config { - pins = "sdc2_clk"; bias-disable; - drive-strength = <2>; }; - }; - sdc2_cmd_on: sdc2_cmd_on { - config { + cmd { pins = "sdc2_cmd"; - bias-pull-up; drive-strength = <10>; + bias-pull-up; + }; + + data { + pins = "sdc2_data"; + drive-strength = <10>; + bias-pull-up; }; }; - sdc2_cmd_off: sdc2_cmd_off { - config { + sdc2_off: sdc2-off { + clk { + pins = "sdc2_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd { pins = "sdc2_cmd"; - bias-pull-up; drive-strength = <2>; + bias-pull-up; }; - }; - sdc2_data_on: sdc2_data_on { - config { + data { pins = "sdc2_data"; - bias-pull-up; - drive-strength = <10>; - }; - }; - - sdc2_data_off: sdc2_data_off { - config { - pins = "sdc2_data"; - bias-pull-up; drive-strength = <2>; - }; - }; - - sdc2_cd_on: sdc2_cd_on { - mux { - pins = "gpio95"; - function = "gpio"; - }; - - config { - pins = "gpio95"; bias-pull-up; - drive-strength = <2>; }; }; - sdc2_cd_off: sdc2_cd_off { - mux { - pins = "gpio95"; - function = "gpio"; - }; - - config { - pins = "gpio95"; - bias-pull-up; - drive-strength = <2>; - }; + sdc2_cd: sdc2-cd { + pins = "gpio95"; + function = "gpio"; + bias-pull-up; + drive-strength = <2>; }; - blsp1_uart3_on: blsp1_uart3_on { + mclk0_on: mclk0-on { + pins = "gpio13"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + mclk0_off: mclk0-off { + pins = "gpio13"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + + mclk1_on: mclk1-on { + pins = "gpio14"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + mclk1_off: mclk1-off { + pins = "gpio14"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + + mclk2_on: mclk2-on { + pins = "gpio15"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + mclk2_off: mclk2-off { + pins = "gpio15"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + + mclk3_on: mclk3-on { + pins = "gpio16"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + mclk3_off: mclk3-off { + pins = "gpio16"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + + cci0_on: cci0-on { + pins = "gpio17", "gpio18"; + function = "cci_i2c"; + drive-strength = <2>; + bias-disable; + }; + + cci0_off: cci0-off { + pins = "gpio17", "gpio18"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-down; + }; + + cci1_on: cci1-on { + pins = "gpio19", "gpio20"; + function = "cci_i2c"; + drive-strength = <2>; + bias-disable; + }; + + cci1_off: cci1-off { + pins = "gpio19", "gpio20"; + function = "cci_i2c"; + drive-strength = <2>; + bias-pull-down; + }; + + blsp1_uart3_on: blsp1-uart3-on { tx { pins = "gpio45"; function = "blsp_uart3_a"; @@ -1394,6 +2167,8 @@ "rbcpr", "core"; + interconnects = <&bimc MASTER_OXILI &bimc SLAVE_EBI>; + interconnect-names = "gfx-mem"; interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>; iommus = <&adreno_smmu 0>; operating-points-v2 = <&gpu_opp_table>; @@ -1405,49 +2180,63 @@ opp-710000097 { opp-hz = /bits/ 64 <710000097>; opp-level = ; + opp-peak-kBps = <14432000>; + opp-avg-kBps = <14400000>; opp-supported-hw = <0xFF>; }; opp-670000048 { opp-hz = /bits/ 64 <670000048>; opp-level = ; + opp-peak-kBps = <14432000>; + opp-avg-kBps = <14390000>; opp-supported-hw = <0xFF>; }; - opp-596000097 { opp-hz = /bits/ 64 <596000097>; opp-level = ; + opp-peak-kBps = <14432000>; + opp-avg-kBps = <12440000>; opp-supported-hw = <0xFF>; }; opp-515000097 { opp-hz = /bits/ 64 <515000097>; opp-level = ; + opp-peak-kBps = <14432000>; + opp-avg-kBps = <10368000>; opp-supported-hw = <0xFF>; }; opp-414000000 { opp-hz = /bits/ 64 <414000000>; opp-level = ; + opp-peak-kBps = <12440000>; + opp-avg-kBps = <8136000>; opp-supported-hw = <0xFF>; }; opp-342000000 { opp-hz = /bits/ 64 <342000000>; opp-level = ; + opp-peak-kBps = <8136000>; + opp-avg-kBps = <6144000>; opp-supported-hw = <0xFF>; }; opp-257000000 { opp-hz = /bits/ 64 <257000000>; opp-level = ; + opp-peak-kBps = <6144000>; + opp-avg-kBps = <3296000>; opp-supported-hw = <0xFF>; }; }; }; adreno_smmu: iommu@5040000 { - compatible = "qcom,msm8998-smmu-v2", "qcom,smmu-v2"; + compatible = "qcom,msm8998-smmu-v2", "qcom,smmu-v2", + "qcom,adreno-smmu"; reg = <0x05040000 0x10000>; clocks = <&gcc GCC_GPU_CFG_AHB_CLK>, <&gcc GCC_BIMC_GFX_CLK>, @@ -1469,7 +2258,6 @@ * SoC VDDMX RPM Power Domain in the Adreno driver. */ power-domains = <&gpucc GPU_GX_GDSC>; - status = "disabled"; }; gpucc: clock-controller@5065000 { @@ -1485,6 +2273,33 @@ "gpll0"; }; + lpass_q6_smmu: iommu@5100000 { + compatible = "qcom,msm8998-smmu-v2", "qcom,smmu-v2"; + reg = <0x05100000 0x40000>; + clocks = <&gcc HLOS1_VOTE_LPASS_ADSP_SMMU_CLK>; + clock-names = "iface"; + + #global-interrupts = <0>; + #iommu-cells = <1>; + interrupts = + , + , + , + , + , + , + , + , + , + , + , + , + ; + + power-domains = <&gcc LPASS_ADSP_GDSC>; + status = "disabled"; + }; + remoteproc_slpi: remoteproc@5800000 { compatible = "qcom,msm8998-slpi-pas"; reg = <0x05800000 0x4040>; @@ -2089,6 +2904,7 @@ reg = <0x0c0a4900 0x314>, <0x0c0a4000 0x800>; reg-names = "hc_mem", "core_mem"; + interconnects = <&a2noc MASTER_SDCC_2 &a2noc SLAVE_A2NOC_SNOC>; interrupts = , ; interrupt-names = "hc_irq", "pwr_irq"; @@ -2099,6 +2915,26 @@ <&xo>; bus-width = <4>; status = "disabled"; + + sdhc2_opp_table: sdhc2-opp-table { + compatible = "operating-points-v2"; + + opp-50000000 { + opp-hz = /bits/ 64 <50000000>; + opp-peak-kBps = <400000>; + opp-avg-kBps = <200000>; + }; + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-peak-kBps = <800000>; + opp-avg-kBps = <400000>; + }; + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-peak-kBps = <800000>; + opp-avg-kBps = <800000>; + }; + }; }; blsp1_dma: dma-controller@c144000 { @@ -2397,7 +3233,6 @@ #reset-cells = <1>; #power-domain-cells = <1>; reg = <0xc8c0000 0x40000>; - status = "disabled"; clock-names = "xo", "gpll0", @@ -2411,16 +3246,473 @@ "core_bi_pll_test_se"; clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, <&gcc GCC_MMSS_GPLL0_CLK>, - <0>, - <0>, - <0>, - <0>, + <&dsi0_phy 1>, + <&dsi0_phy 0>, + <&dsi1_phy 1>, + <&dsi1_phy 0>, <0>, <0>, <0>, <0>; }; + dsi_opp_table: dsi-opp-table { + compatible = "operating-points-v2"; + + opp-131250000 { + opp-hz = /bits/ 64 <131250000>; + required-opps = <&rpmpd_opp_low_svs>; + }; + + opp-210000000 { + opp-hz = /bits/ 64 <210000000>; + required-opps = <&rpmpd_opp_svs>; + }; + + opp-312500000 { + opp-hz = /bits/ 64 <312500000>; + required-opps = <&rpmpd_opp_nom>; + }; + }; + + mdss: mdss@c900000 { + compatible = "qcom,sdm845-mdss"; + reg = <0x0c900000 0x1000>; + reg-names = "mdss"; + + clocks = <&mmcc MDSS_AHB_CLK>, + <&mmcc MDSS_AXI_CLK>, + <&mmcc MDSS_MDP_CLK>; + clock-names = "iface", "bus", "core"; + + assigned-clocks = <&mmcc MDSS_MDP_CLK>; + assigned-clock-rates = <300000000>; + interconnects = <&mnoc MASTER_MDP_P0 &bimc SLAVE_EBI>, + <&mnoc MASTER_MDP_P1 &bimc SLAVE_EBI>; + interconnect-names = "mdp0-mem", + "mdp1-mem"; + interrupts = ; + interrupt-controller; + iommus = <&mmss_smmu 0>; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + power-domains = <&mmcc MDSS_GDSC>; + ranges; + status = "disabled"; + + mdss_mdp: mdp@c901000 { + compatible = "qcom,msm8998-dpu"; + reg = <0x0c901000 0x8f000>, + <0x0c9a8e00 0xf0>, + <0x0c9b0000 0x2008>, + <0x0c9b8000 0x1040>; + reg-names = "mdp", "regdma", "vbif", + "vbif_nrt"; + + assigned-clocks = <&mmcc MDSS_MDP_CLK>, + <&mmcc MDSS_VSYNC_CLK>; + assigned-clock-rates = <412500000>, + <19200000>; + + clocks = <&mmcc MDSS_AHB_CLK>, + <&mmcc MDSS_AXI_CLK>, + <&mmcc MNOC_AHB_CLK>, + <&mmcc MDSS_MDP_CLK>, + <&mmcc MDSS_VSYNC_CLK>; + clock-names = "iface", "bus", "mnoc", + "core", "vsync"; + + interrupt-parent = <&mdss>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + operating-points-v2 = <&mdp_opp_table>; + power-domains = <&rpmpd MSM8998_VDDMX>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpu_intf1_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; + + port@1 { + reg = <1>; + dpu_intf2_out: endpoint { + remote-endpoint = <&dsi1_in>; + }; + }; + }; + + mdp_opp_table: mdp-opp-table { + compatible = "operating-points-v2"; + + opp-19200000 { + opp-hz = /bits/ 64 <19200000>; + required-opps = <&rpmpd_opp_min_svs>; + }; + + opp-150000000 { + opp-hz = /bits/ 64 <150000000>; + required-opps = <&rpmpd_opp_low_svs>; + }; + + opp-275000000 { + opp-hz = /bits/ 64 <275000000>; + required-opps = <&rpmpd_opp_svs>; + }; + + opp-330000000 { + opp-hz = /bits/ 64 <330000000>; + required-opps = <&rpmpd_opp_nom>; + }; + + opp-412500000 { + opp-hz = /bits/ 64 <412500000>; + required-opps = <&rpmpd_opp_turbo>; + }; + }; + }; + + dsi0: dsi@c994000 { + compatible = "qcom,mdss-dsi-ctrl"; + reg = <0x0c994000 0x400>; + reg-names = "dsi_ctrl"; + + clocks = <&mmcc MDSS_BYTE0_CLK>, + <&mmcc MDSS_BYTE0_INTF_CLK>, + <&mmcc MNOC_AHB_CLK>, + <&mmcc MDSS_AHB_CLK>, + <&mmcc MDSS_AXI_CLK>, + <&mmcc MISC_AHB_CLK>, + <&mmcc MDSS_PCLK0_CLK>, + <&mmcc MDSS_ESC0_CLK>; + clock-names = "byte", + "byte_intf", + "mnoc", + "iface", + "bus", + "core_mmss", + "pixel", + "core"; + + interrupt-parent = <&mdss>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + operating-points-v2 = <&dsi_opp_table>; + phys = <&dsi0_phy>; + phy-names = "dsi"; + power-domains = <&rpmpd MSM8998_VDDCX>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi0_in: endpoint { + remote-endpoint = <&dpu_intf1_out>; + }; + }; + + port@1 { + reg = <1>; + dsi0_out: endpoint { + }; + }; + }; + }; + + dsi0_phy: dsi-phy@c994400 { + compatible = "qcom,dsi-phy-10nm-8998"; + reg = <0x0c994400 0x200>, + <0x0c994600 0x280>, + <0x0c994a00 0x1c0>; + reg-names = "dsi_phy", + "dsi_phy_lane", + "dsi_pll"; + + #clock-cells = <1>; + #phy-cells = <0>; + + clocks = <&mmcc MDSS_AHB_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "iface", "ref"; + power-domains = <&rpmpd MSM8998_VDDMX>; + + status = "disabled"; + }; + + dsi1: dsi@c996000 { + compatible = "qcom,mdss-dsi-ctrl"; + reg = <0x0c996000 0x400>; + reg-names = "dsi_ctrl"; + + clocks = <&mmcc MDSS_BYTE1_CLK>, + <&mmcc MDSS_BYTE1_INTF_CLK>, + <&mmcc MNOC_AHB_CLK>, + <&mmcc MISC_AHB_CLK>, + <&mmcc MDSS_PCLK1_CLK>, + <&mmcc MDSS_ESC1_CLK>, + <&mmcc MDSS_AHB_CLK>, + <&mmcc MDSS_AXI_CLK>; + clock-names = "byte", + "byte_intf", + "mnoc", + "iface_mmss", + "pixel", + "core", + "iface", + "bus"; + + interrupt-parent = <&mdss>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + operating-points-v2 = <&dsi_opp_table>; + phys = <&dsi1_phy>; + phy-names = "dsi"; + power-domains = <&rpmpd MSM8998_VDDCX>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi1_in: endpoint { + remote-endpoint = <&dpu_intf2_out>; + }; + }; + + port@1 { + reg = <1>; + dsi1_out: endpoint { + }; + }; + }; + }; + + dsi1_phy: dsi-phy@c996400 { + compatible = "qcom,dsi-phy-10nm-8998"; + reg = <0x0c996400 0x200>, + <0x0c996600 0x280>, + <0x0c996a00 0x10e>; + reg-names = "dsi_phy", + "dsi_phy_lane", + "dsi_pll"; + + #clock-cells = <1>; + #phy-cells = <0>; + + clocks = <&mmcc MDSS_AHB_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "iface", "ref"; + power-domains = <&rpmpd MSM8998_VDDMX>; + + status = "disabled"; + }; + }; + + camss: camss@ca30000 { + compatible = "qcom,msm8998-camss"; + reg = <0x0ca34000 0x1000>, + <0x0ca35000 0x1000>, + <0x0ca36000 0x1000>, + <0x0ca30000 0x100>, + <0x0ca30400 0x100>, + <0x0ca30800 0x100>, + <0x0ca30c00 0x100>, + <0x0ca31000 0x500>, + <0x0ca00020 0x10>, + <0x0ca10000 0x4000>, + <0x0ca14000 0x4000>; + reg-names = "csiphy0", + "csiphy1", + "csiphy2", + "csid0", + "csid1", + "csid2", + "csid3", + "ispif", + "csi_clk_mux", + "vfe0", + "vfe1"; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "csiphy0", + "csiphy1", + "csiphy2", + "csid0", + "csid1", + "csid2", + "csid3", + "ispif", + "vfe0", + "vfe1"; + clocks = <&mmcc CAMSS_TOP_AHB_CLK>, + <&mmcc CAMSS_ISPIF_AHB_CLK>, + <&mmcc CAMSS_CSI0PHYTIMER_CLK>, + <&mmcc CAMSS_CSI1PHYTIMER_CLK>, + <&mmcc CAMSS_CSI2PHYTIMER_CLK>, + <&mmcc CAMSS_CSI0_AHB_CLK>, + <&mmcc CAMSS_CSI0_CLK>, + <&mmcc CAMSS_CPHY_CSID0_CLK>, + <&mmcc CAMSS_CSI0PIX_CLK>, + <&mmcc CAMSS_CSI0RDI_CLK>, + <&mmcc CAMSS_CSI1_AHB_CLK>, + <&mmcc CAMSS_CSI1_CLK>, + <&mmcc CAMSS_CPHY_CSID1_CLK>, + <&mmcc CAMSS_CSI1PIX_CLK>, + <&mmcc CAMSS_CSI1RDI_CLK>, + <&mmcc CAMSS_CSI2_AHB_CLK>, + <&mmcc CAMSS_CSI2_CLK>, + <&mmcc CAMSS_CPHY_CSID2_CLK>, + <&mmcc CAMSS_CSI2PIX_CLK>, + <&mmcc CAMSS_CSI2RDI_CLK>, + <&mmcc CAMSS_CSI3_AHB_CLK>, + <&mmcc CAMSS_CSI3_CLK>, + <&mmcc CAMSS_CPHY_CSID3_CLK>, + <&mmcc CAMSS_CSI3PIX_CLK>, + <&mmcc CAMSS_CSI3RDI_CLK>, + <&mmcc CAMSS_AHB_CLK>, + <&mmcc CAMSS_VFE0_CLK>, + <&mmcc CAMSS_CSI_VFE0_CLK>, + <&mmcc CAMSS_VFE0_AHB_CLK>, + <&mmcc CAMSS_VFE0_STREAM_CLK>, + <&mmcc CAMSS_VFE1_CLK>, + <&mmcc CAMSS_CSI_VFE1_CLK>, + <&mmcc CAMSS_VFE1_AHB_CLK>, + <&mmcc CAMSS_VFE1_STREAM_CLK>, + <&mmcc CAMSS_VFE_VBIF_AHB_CLK>, + <&mmcc CAMSS_VFE_VBIF_AXI_CLK>, + <&mmcc CAMSS_CPHY_CSID0_CLK>, + <&mmcc CAMSS_CPHY_CSID1_CLK>, + <&mmcc CAMSS_CPHY_CSID2_CLK>, + <&mmcc CAMSS_CPHY_CSID3_CLK>; + clock-names = "top_ahb", + "ispif_ahb", + "csiphy0_timer", + "csiphy1_timer", + "csiphy2_timer", + "csi0_ahb", + "csi0", + "csi0_phy", + "csi0_pix", + "csi0_rdi", + "csi1_ahb", + "csi1", + "csi1_phy", + "csi1_pix", + "csi1_rdi", + "csi2_ahb", + "csi2", + "csi2_phy", + "csi2_pix", + "csi2_rdi", + "csi3_ahb", + "csi3", + "csi3_phy", + "csi3_pix", + "csi3_rdi", + "ahb", + "vfe0", + "csi_vfe0", + "vfe0_ahb", + "vfe0_stream", + "vfe1", + "csi_vfe1", + "vfe1_ahb", + "vfe1_stream", + "vfe_ahb", + "vfe_axi", + "cphy_csid0", + "cphy_csid1", + "cphy_csid2", + "cphy_csid3"; + iommus = <&mmss_smmu 0xc00>, + <&mmss_smmu 0xc01>, + <&mmss_smmu 0xc02>, + <&mmss_smmu 0xc03>; + power-domains = <&mmcc CAMSS_VFE0_GDSC>, + <&mmcc CAMSS_VFE1_GDSC>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + csiphy0_ep: endpoint { + }; + }; + + port@1 { + reg = <1>; + csiphy1_ep: endpoint { + }; + }; + + port@2 { + reg = <2>; + csiphy2_ep: endpoint { + }; + }; + }; + }; + + cci: cci@ca0c000 { + compatible = "qcom,msm8996-cci"; + reg = <0x0ca0c000 0x4000>; + + interrupts = ; + assigned-clocks = <&mmcc CAMSS_CCI_AHB_CLK>, <&mmcc CAMSS_CCI_CLK>; + assigned-clock-rates = <80800000>, <37500000>; + clocks = <&mmcc CAMSS_TOP_AHB_CLK>, + <&mmcc CAMSS_CCI_AHB_CLK>, + <&mmcc CAMSS_CCI_CLK>, + <&mmcc CAMSS_AHB_CLK>; + clock-names = "camss_top_ahb", + "cci_ahb", + "cci", + "camss_ahb"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&cci0_on &cci1_on>; + pinctrl-1 = <&cci0_off &cci1_off>; + power-domains = <&mmcc CAMSS_TOP_GDSC>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + + cci_i2c0: i2c-bus@0 { + reg = <0>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + cci_i2c1: i2c-bus@1 { + reg = <1>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + mmss_smmu: iommu@cd00000 { compatible = "qcom,msm8998-smmu-v2", "qcom,smmu-v2"; reg = <0x0cd00000 0x40000>; @@ -2432,7 +3724,6 @@ <&mmcc BIMC_SMMU_AXI_CLK>; clock-names = "iface-mm", "iface-smmu", "bus-mm", "bus-smmu"; - status = "disabled"; #global-interrupts = <0>; interrupts = @@ -2458,6 +3749,56 @@ ; }; + imem@146bf000 { + compatible = "simple-mfd"; + reg = <0x146bf000 0x1000>; + + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0 0x146bf000 0x1000>; + + pil-reloc@94c { + compatible = "qcom,pil-reloc-info"; + reg = <0x94c 0xc8>; + }; + }; + + slimbam: dma-controller@17184000 { + compatible = "qcom,bam-v1.7.0"; + qcom,controlled-remotely; + reg = <0x17184000 0x32000>; + num-channels = <31>; + interrupts = ; + #dma-cells = <1>; + qcom,ee = <1>; + qcom,num-ees = <2>; + status = "disabled"; + }; + + slim: slim@171c0000 { + compatible = "qcom,slim-ngd-v2.1.0"; + reg = <0x171c0000 0x2c000>; + interrupts = ; + + qcom,apps-ch-pipes = <0x1f80>; + qcom,ea-pc = <0x210>; + + dmas = <&slimbam 3>, <&slimbam 4>, + <&slimbam 5>, <&slimbam 6>; + dma-names = "rx", "tx", "tx2", "rx2"; + + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + slim_ngd: ngd@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + remoteproc_adsp: remoteproc@17300000 { compatible = "qcom,msm8998-adsp-pas"; reg = <0x17300000 0x4040>; @@ -2488,9 +3829,134 @@ label = "lpass"; qcom,remote-pid = <2>; mboxes = <&apcs_glb 9>; + + apr { + compatible = "qcom,apr-v2"; + power-domains = <&gcc LPASS_ADSP_GDSC>; + qcom,glink-channels = "apr_audio_svc"; + qcom,apr-domain = ; + #address-cells = <1>; + #size-cells = <0>; + qcom,intents = <512 20>; + + apr-service@3 { + reg = ; + compatible = "qcom,q6core"; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + }; + + q6afe: apr-service@4 { + compatible = "qcom,q6afe"; + reg = ; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + q6afedai: dais { + compatible = "qcom,q6afe-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + hdmi@1 { + reg = <1>; + }; + }; + }; + + q6asm: apr-service@7 { + compatible = "qcom,q6asm"; + reg = ; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + q6asmdai: dais { + compatible = "qcom,q6asm-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + iommus = <&lpass_q6_smmu 1>; + }; + }; + + q6adm: apr-service@8 { + compatible = "qcom,q6adm"; + reg = ; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + q6routing: routing { + compatible = "qcom,q6adm-routing"; + #sound-dai-cells = <0>; + }; + }; + }; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + #address-cells = <1>; + #size-cells = <0>; + + cb@2 { + compatible = "qcom,fastrpc-compute-cb"; + //dma-ranges = <0 0x60000000 0 0x18000000>; + reg = <2>; + iommus = <&lpass_q6_smmu 2>; + }; + + cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&lpass_q6_smmu 5>; + }; + + cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + iommus = <&lpass_q6_smmu 6>; + }; + }; }; }; + gnoc: interconnect@17900000 { + compatible = "qcom,msm8998-gnoc"; + reg = <0x17900000 0xe000>; + #interconnect-cells = <1>; + /* + * This one apparently features no clocks, + * so let's not mess with the driver needlessly + */ + clock-names = "bus", "bus_a"; + clocks = <&xo>, <&xo>; + }; + + power-controller@17812000 { + compatible = "qcom,msm8998-gold-saw2-v4.1-l2", + "qcom,saw2"; + reg = <0x017812000 0x1000>; + }; + + power-controller@17912000 { + compatible = "qcom,msm8998-silver-saw2-v4.1-l2", + "qcom,saw2"; + reg = <0x017912000 0x1000>; + }; + + cpufreq_hw: cpufreq_hw@17814800 { + compatible = "qcom,cpufreq-hw-8998"; + reg = <0x017914800 0x100>, <0x017814800 0x100>, + <0x0179c0000 0x1000>, <0x0179c1000 0x1000>, + <0x0179c2000 0x1000>, <0x0179c3000 0x1000>; + reg-names = "osm-acd0", "osm-acd1", + "osm-domain0", "freq-domain0", + "osm-domain1", "freq-domain1"; + + assigned-clocks = <&gcc HMSS_GPLL0_CLK_SRC>; + assigned-clock-rates = <300000000>; + + clocks = <&rpmcc RPM_SMD_XO_A_CLK_SRC>, + <&gcc HMSS_GPLL0_CLK_SRC>; + clock-names = "xo", "alternate"; + + #freq-domain-cells = <1>; + status = "disabled"; + }; + apcs_glb: mailbox@17911000 { compatible = "qcom,msm8998-apcs-hmss-global"; reg = <0x17911000 0x1000>; @@ -2556,6 +4022,92 @@ }; }; + /* Gold and Silver cluster */ + apc_cprh: power-controller@179c8000 { + compatible = "qcom,msm8998-cprh"; + reg = <0x0179c8000 0x4000>, <0x0179c4000 0x4000>; + + assigned-clocks = <&gcc GCC_HMSS_RBCPR_CLK>; + assigned-clock-rates = <19200000>; + clocks = <&gcc GCC_HMSS_RBCPR_CLK>; + clock-names = "ref"; + + operating-points-v2 = <&cprh_opp_table>; + power-domains = <&rpmpd MSM8998_VDDCX_AO>; + #power-domain-cells = <1>; + status = "disabled"; + + nvmem-cells = <&cpr_efuse_speedbin>, + <&cpr_fuse_revision>, + <&cpr_quot0_pwrcl>, + <&cpr_quot1_pwrcl>, + <&cpr_quot2_pwrcl>, + <&cpr_quot3_pwrcl>, + <&cpr_quot_offset1_pwrcl>, + <&cpr_quot_offset2_pwrcl>, + <&cpr_quot_offset3_pwrcl>, + <&cpr_init_voltage0_pwrcl>, + <&cpr_init_voltage1_pwrcl>, + <&cpr_init_voltage2_pwrcl>, + <&cpr_init_voltage3_pwrcl>, + <&cpr_ro_sel0_pwrcl>, + <&cpr_ro_sel1_pwrcl>, + <&cpr_ro_sel2_pwrcl>, + <&cpr_ro_sel3_pwrcl>, + <&cpr_aging_quot_off_pwrcl>, + <&cpr_quot0_perfcl>, + <&cpr_quot1_perfcl>, + <&cpr_quot2_perfcl>, + <&cpr_quot3_perfcl>, + <&cpr_quot_offset1_perfcl>, + <&cpr_quot_offset2_perfcl>, + <&cpr_quot_offset3_perfcl>, + <&cpr_init_voltage0_perfcl>, + <&cpr_init_voltage1_perfcl>, + <&cpr_init_voltage2_perfcl>, + <&cpr_init_voltage3_perfcl>, + <&cpr_ro_sel0_perfcl>, + <&cpr_ro_sel1_perfcl>, + <&cpr_ro_sel2_perfcl>, + <&cpr_ro_sel3_perfcl>, + <&cpr_aging_quot_off_perfcl>; + + nvmem-cell-names = "cpr_speed_bin", + "cpr_fuse_revision", + "cpr0_quotient1", + "cpr0_quotient2", + "cpr0_quotient3", + "cpr0_quotient4", + "cpr0_quotient_offset2", + "cpr0_quotient_offset3", + "cpr0_quotient_offset4", + "cpr0_init_voltage1", + "cpr0_init_voltage2", + "cpr0_init_voltage3", + "cpr0_init_voltage4", + "cpr0_ring_osc1", + "cpr0_ring_osc2", + "cpr0_ring_osc3", + "cpr0_ring_osc4", + "cpr0_aging_quotient", + "cpr1_quotient1", + "cpr1_quotient2", + "cpr1_quotient3", + "cpr1_quotient4", + "cpr1_quotient_offset2", + "cpr1_quotient_offset3", + "cpr1_quotient_offset4", + "cpr1_init_voltage1", + "cpr1_init_voltage2", + "cpr1_init_voltage3", + "cpr1_init_voltage4", + "cpr1_ring_osc1", + "cpr1_ring_osc2", + "cpr1_ring_osc3", + "cpr1_ring_osc4", + "cpr1_aging_quotient"; + }; + intc: interrupt-controller@17a00000 { compatible = "arm,gic-v3"; reg = <0x17a00000 0x10000>, /* GICD */ diff --git a/arch/arm64/boot/dts/qcom/pm8005.dtsi b/arch/arm64/boot/dts/qcom/pm8005.dtsi index 3f97607d8baa..50fb6c753bf8 100644 --- a/arch/arm64/boot/dts/qcom/pm8005.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8005.dtsi @@ -28,5 +28,9 @@ reg = <0x5 SPMI_USID>; #address-cells = <1>; #size-cells = <0>; + + pm8005_regulators: regulators { + compatible = "qcom,pm8005-regulators"; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi index d09f2954b6f9..ed68f44a7f11 100644 --- a/arch/arm64/boot/dts/qcom/pm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi @@ -78,6 +78,16 @@ #size-cells = <0>; #io-channel-cells = <1>; + adc-chan@0 { + reg = ; + label = "ref_gnd"; + }; + + adc-chan@1 { + reg = ; + label = "vref_1p25"; + }; + adc-chan@6 { reg = ; label = "die_temp"; diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi index 0fef5f113f05..3ace95925bf5 100644 --- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include @@ -9,6 +10,23 @@ #address-cells = <1>; #size-cells = <0>; + pmi8998_charger: charger@1000 { + compatible = "qcom,pmi8998-charger"; + reg = <0x1000>; + + interrupts = <0x2 0x13 0x4 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x12 0x2 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x16 0x1 IRQ_TYPE_EDGE_RISING>, + <0x2 0x13 0x6 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "usb-plugin", "bat-ov", "wdog-bark", "usbin-icl-change"; + + io-channels = <&pmi8998_rradc 3>, + <&pmi8998_rradc 4>; + io-channel-names = "usbin_i", "usbin_v"; + + status = "disabled"; + }; + pmi8998_gpio: gpios@c000 { compatible = "qcom,pmi8998-gpio", "qcom,spmi-gpio"; reg = <0xc000>; @@ -18,6 +36,14 @@ interrupt-controller; #interrupt-cells = <2>; }; + + pmi8998_rradc: rradc@4500 { + compatible = "qcom,pmi8998-rradc"; + reg = <0x4500>; + #io-channel-cells = <1>; + + status = "disabled"; + }; }; pmi8998_lsid1: pmic@3 { @@ -53,5 +79,29 @@ status = "disabled"; }; + pmi8998_haptics: haptics@c000 { + compatible = "qcom,spmi-haptics"; + reg = <0xc000>; + + interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>, + <0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "short", "play"; + + qcom,wave-shape = ; + qcom,play-mode = ; + qcom,brake-pattern = <0x3 0x3 0x2 0x1>; + + status = "disabled"; + }; + + pmi8998_lpg: led-controller { + compatible = "qcom,pmi8998-lpg"; + + #address-cells = <1>; + #size-cells = <0>; + #pwm-cells = <2>; + + status = "disabled"; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi index 3f06f7cd3cf2..eca0661a8f09 100644 --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -1173,19 +1173,19 @@ <&cpr_efuse_ring2>, <&cpr_efuse_ring3>, <&cpr_efuse_revision>; - nvmem-cell-names = "cpr_quotient_offset1", - "cpr_quotient_offset2", - "cpr_quotient_offset3", - "cpr_init_voltage1", - "cpr_init_voltage2", - "cpr_init_voltage3", - "cpr_quotient1", - "cpr_quotient2", - "cpr_quotient3", - "cpr_ring_osc1", - "cpr_ring_osc2", - "cpr_ring_osc3", - "cpr_fuse_revision"; + nvmem-cell-names = "cpr0_quotient_offset1", + "cpr0_quotient_offset2", + "cpr0_quotient_offset3", + "cpr0_init_voltage1", + "cpr0_init_voltage2", + "cpr0_init_voltage3", + "cpr0_quotient1", + "cpr0_quotient2", + "cpr0_quotient3", + "cpr0_ring_osc1", + "cpr0_ring_osc2", + "cpr0_ring_osc3", + "cpr0_fuse_revision"; }; timer@b120000 { diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c index 407e2c5caea4..d85091e6cd5d 100644 --- a/drivers/clk/qcom/gcc-msm8998.c +++ b/drivers/clk/qcom/gcc-msm8998.c @@ -2080,6 +2080,7 @@ static struct clk_branch gcc_bimc_gfx_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_bimc_gfx_clk", + .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -2220,6 +2221,7 @@ static struct clk_rcg2 hmss_gpll0_clk_src = { .name = "hmss_gpll0_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_IS_CRITICAL, .ops = &clk_rcg2_ops, }, }; @@ -2833,6 +2835,43 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = { }, }; +static struct clk_branch hlos1_vote_lpass_core_smmu_clk = { + .halt_reg = 0x7D010, + .clkr = { + .enable_reg = 0x7D010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "hlos1_vote_lpass_core_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch hlos1_vote_lpass_adsp_smmu_clk = { + .halt_reg = 0x7D014, + .clkr = { + .enable_reg = 0x7D014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "hlos1_vote_lpass_adsp_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x8A040, + .clkr = { + .enable_reg = 0x8A040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "gcc_mss_q6_bimc_axi_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc pcie_0_gdsc = { .gdscr = 0x6b004, .gds_hw_ctrl = 0x0, @@ -2863,6 +2902,26 @@ static struct gdsc usb_30_gdsc = { .flags = VOTABLE, }; +static struct gdsc hlos1_vote_lpass_adsp = { + .gdscr = 0x7d034, + .gds_hw_ctrl = 0x0, + .pd = { + .name = "lpass_adsp_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_lpass_core = { + .gdscr = 0x7d038, + .gds_hw_ctrl = 0x0, + .pd = { + .name = "lpass_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = ALWAYS_ON, +}; + static struct clk_regmap *gcc_msm8998_clocks[] = { [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, @@ -3036,12 +3095,17 @@ static struct clk_regmap *gcc_msm8998_clocks[] = { [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, [GCC_MMSS_GPLL0_CLK] = &gcc_mmss_gpll0_clk.clkr, [HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [HLOS1_VOTE_LPASS_CORE_SMMU_CLK] = &hlos1_vote_lpass_core_smmu_clk.clkr, + [HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] = &hlos1_vote_lpass_adsp_smmu_clk.clkr, }; static struct gdsc *gcc_msm8998_gdscs[] = { [PCIE_0_GDSC] = &pcie_0_gdsc, [UFS_GDSC] = &ufs_gdsc, [USB_30_GDSC] = &usb_30_gdsc, + [LPASS_ADSP_GDSC] = &hlos1_vote_lpass_adsp, + [LPASS_CORE_GDSC] = &hlos1_vote_lpass_core, }; static const struct qcom_reset_map gcc_msm8998_resets[] = { @@ -3191,6 +3255,14 @@ static int gcc_msm8998_probe(struct platform_device *pdev) if (ret) return ret; + /* + * GCC_MMSS_MISC - GCC_GPU_MISC: + * 1. Disable the GPLL0 active input to MMSS and GPU + * 2. Select clk division 1 (CLK/2) + */ + regmap_write(regmap, 0x0902C, 0x10003); /* MMSS*/ + regmap_write(regmap, 0x71028, 0x10003); /* GPU */ + return qcom_cc_really_probe(pdev, &gcc_msm8998_desc, regmap); } diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c index c421b1291651..07dfdb9e280d 100644 --- a/drivers/clk/qcom/mmcc-msm8998.c +++ b/drivers/clk/qcom/mmcc-msm8998.c @@ -511,7 +511,7 @@ static struct clk_rcg2 byte0_clk_src = { .parent_data = mmss_xo_dsibyte, .num_parents = ARRAY_SIZE(mmss_xo_dsibyte), .ops = &clk_byte2_ops, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -524,7 +524,7 @@ static struct clk_rcg2 byte1_clk_src = { .parent_data = mmss_xo_dsibyte, .num_parents = ARRAY_SIZE(mmss_xo_dsibyte), .ops = &clk_byte2_ops, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1075,7 +1075,7 @@ static struct clk_rcg2 pclk0_clk_src = { .parent_data = mmss_xo_dsi0pll_dsi1pll, .num_parents = ARRAY_SIZE(mmss_xo_dsi0pll_dsi1pll), .ops = &clk_pixel_ops, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1089,7 +1089,7 @@ static struct clk_rcg2 pclk1_clk_src = { .parent_data = mmss_xo_dsi0pll_dsi1pll, .num_parents = ARRAY_SIZE(mmss_xo_dsi0pll_dsi1pll), .ops = &clk_pixel_ops, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, }; diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 96de1536e1cb..2bcc907660b4 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -137,6 +137,7 @@ static const struct of_device_id blocklist[] __initconst = { { .compatible = "qcom,apq8096", }, { .compatible = "qcom,msm8996", }, + { .compatible = "qcom,msm8998", }, { .compatible = "qcom,qcs404", }, { .compatible = "qcom,sa8155p" }, { .compatible = "qcom,sa8540p" }, diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index 0253731d6d25..b82e2f8ea04b 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -1,43 +1,266 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * OSM hardware initial programming + * Copyright (C) 2020, AngeloGioacchino Del Regno + * */ #include #include +#include #include #include #include +#include #include #include #include #include +#include #include #include #include +#include +#include #define LUT_MAX_ENTRIES 40U -#define LUT_SRC GENMASK(31, 30) +#define LUT_SRC_845 GENMASK(31, 30) +#define LUT_SRC_8998 GENMASK(27, 26) +#define LUT_PLL_DIV GENMASK(25, 24) #define LUT_L_VAL GENMASK(7, 0) #define LUT_CORE_COUNT GENMASK(18, 16) +#define LUT_VOLT_VC GENMASK(21, 16) #define LUT_VOLT GENMASK(11, 0) -#define CLK_HW_DIV 2 #define LUT_TURBO_IND 1 +#define OSM_BOOT_TIME_US 5 + +#define CYCLE_COUNTER_CLK_RATIO GENMASK(5, 1) +#define OSM_XO_RATIO_VAL (10 - 1) +#define CYCLE_COUNTER_USE_XO_EDGE BIT(8) + +/* FSM Boost Control */ +#define CC_BOOST_EN BIT(0) +#define PS_BOOST_EN BIT(1) +#define DCVS_BOOST_EN BIT(2) +#define BOOST_TIMER_REG_HI GENMASK(31, 16) +#define BOOST_TIMER_REG_LO GENMASK(15, 0) + +#define PLL_WAIT_LOCK_TIME_NS 2000 +#define SAFE_FREQ_WAIT_NS 1000 +#define DEXT_DECREMENT_WAIT_NS 200 + +#define BOOST_SYNC_DELAY 5 + +#define HYSTERESIS_UP_MASK GENMASK(31, 16) +#define HYSTERESIS_DN_MASK GENMASK(15, 0) +#define HYSTERESIS_CC_NS 200 +#define HYSTERESIS_LLM_NS 65535 + +/* FSM Droop Control */ +#define PC_RET_EXIT_DROOP_EN BIT(3) +#define WFX_DROOP_EN BIT(4) +#define DCVS_DROOP_EN BIT(5) +#define DROOP_TIMER1 GENMASK(31, 16) +#define DROOP_TIMER0 GENMASK(15, 0) +#define DROOP_CTRL_VAL (BIT(3) | BIT(17) | BIT(31)) +#define DROOP_TIMER_NS 100 +#define DROOP_WAIT_RELEASE_TIMER_NS 50 +#define DROOP_RELEASE_TIMER_NS 1 + +/* PLL Override Control */ +#define PLL_OVERRIDE_DROOP_EN BIT(0) + +/* Sequencer */ +#define SEQUENCER_REG(base, n) (base + (n * 4)) +#define SEQ_APM_THRESH_VC 15 +#define SEQ_APM_THRESH_PREVC 31 +#define SEQ_MEM_ACC_LVAL 32 +#define SEQ_MEM_ACC_0 55 +#define SEQ_APM_CROSSOVER_VC 72 +#define SEQ_APM_PARAM 76 +#define SEQ_MEM_ACC_CROSSOVER_VC 88 +#define SEQ_MEM_ACC_MAX_LEVELS 4 +#define SEQ_MEMACC_REG(base, n) SEQUENCER_REG(base, SEQ_MEM_ACC_0 + n) + +/* ACD */ +#define ACD_WRITE_CTL_UPDATE_EN BIT(0) +#define ACD_WRITE_CTL_SELECT_SHIFT 1 + +/** + * struct qcom_cpufreq_soc_setup_data - Register offsets for OSM setup + * + * @reg_osm_sequencer: OSM Sequencer (used to get physical address) + * @reg_override: Override parameters + * @reg_spare: Spare parameters (MEMACC-to-VC) + * @reg_cc_zero_behav: Virtual Corner for cluster power collapse + * @reg_spm_cc_hyst: DCVS-CC Wait time for frequency inc/decrement + * @reg_spm_cc_dcvs_dis: DCVS-CC en/disable control + * @reg_spm_core_ret_map: Treat cores in retention as active/inactive + * @reg_llm_freq_vote_hyst: DCVS-LLM Wait time for frequency inc/decrement + * @reg_llm_volt_vote_hyst: DCVS-LLM Wait time for voltage inc/decrement + * @reg_llm_intf_dcvs_dis: DCVS-LLM en/disable control + * @reg_seq1: Sequencer extra register + * @reg_pdn_fsm_ctrl: Boost and Droop FSMs en/disable control + * @reg_cc_boost_timer: CC-Boost FSM wait first timer register + * @reg_dcvs_boost_timer: DCVS-Boost FSM wait first timer register + * @reg_ps_boost_timer: PS-Boost FSM wait first timer register + * @boost_timer_reg_len: Length of boost timer registers + * @reg_boost_sync_delay: PLL signal timing control for Boost + * @reg_droop_ctrl: Droop control value + * @reg_droop_release_ctrl: Wait for Droop release + * @reg_droop_unstall_ctrl: Wait for Droop unstall + * @reg_droop_wait_release_ctrl: Time to wait for state release + * @reg_droop_timer_ctrl: Droop timer + * @reg_droop_sync_delay: PLL signal timing control for Droop + * @reg_pll_override: PLL Droop Override en/disable control + * @reg_cycle_counter: OSM CPU cycle counter + * + * This structure holds the register offsets that are used to set-up + * the Operating State Manager (OSM) parameters, when it is not (or + * not entirely) configured from the bootloader and TrustZone. + * + * Acronyms used in this documentation: + * CC = Core Count + * PS = Power-Save + * VC = Virtual Corner + * LLM = Limits Load Management + * DCVS = Dynamic Clock and Voltage Scaling + */ +struct qcom_cpufreq_soc_setup_data { + /* OSM phys register offsets */ + u16 reg_osm_sequencer; + + /* Frequency domain register offsets */ + u16 reg_override; + u16 reg_spare; + u16 reg_cc_zero_behav; + u16 reg_spm_cc_hyst; + u16 reg_spm_cc_dcvs_dis; + u16 reg_spm_core_ret_map; + u16 reg_llm_freq_vote_hyst; + u16 reg_llm_volt_vote_hyst; + u16 reg_llm_intf_dcvs_dis; + u16 reg_seq1; + u16 reg_pdn_fsm_ctrl; + u16 reg_cc_boost_timer; + u16 reg_dcvs_boost_timer; + u16 reg_ps_boost_timer; + u16 boost_timer_reg_len; + u16 reg_boost_sync_delay; + u16 reg_droop_ctrl; + u16 reg_droop_release_ctrl; + u16 reg_droop_unstall_ctrl; + u16 reg_droop_wait_release_ctrl; + u16 reg_droop_timer_ctrl; + u16 reg_droop_sync_delay; + u16 reg_pll_override; + u16 reg_cycle_counter; +}; + +/** + * struct qcom_cpufreq_soc_acd_data - Adaptive Clock Distribution data + * + * @tl_delay_reg: Tunable-Length Delay (TLD) register offset + * @acd_ctrl_reg: Control Register (CR) register offset + * @softstart_reg: Soft Start Control Register (SSCR) register offset + * @ext_intf_reg: External interface configuration register offset + * @auto_xfer_reg: Auto Register-Transfer register offset + * @auto_xfer_cfg_reg: Auto Register-Transfer Configuration reg offset + * @auto_xfer_ctl_reg: Auto Register-Transfer Control register offset + * @auto_xfer_sts_reg: Auto Register-Transfer Status register offset + * @dcvs_sw_reg: Software DCVS register offset + * @gfmux_cfg_reg: Glitch-Free MUX configuration register offset + * @write_ctl_reg: Write Control register + * @write_sts_reg: Write Status register + * @tl_delay_val: Tunable-Length Delay (TLD) value + * @acd_ctrl_val: Control Register (CR) value + * @softstart_val: Soft Start Control Register (SSCR) value + * @ext_intf0_val: Initial external interface configuration value + * @ext_intf1_val: Final external interface configuration value + * @auto_xfer_val: Auto-register Transfer Control value + * + * This structure holds the register offsets (from the ACD iospace base) + * and the parameters that are required to configure the OSM to + * initialize the Adaptive Clock Distribution (ACD) system. + */ +struct qcom_cpufreq_soc_acd_data { + u8 tl_delay_reg; + u8 acd_ctrl_reg; + u8 softstart_reg; + u8 ext_intf_reg; + u8 auto_xfer_reg; + u8 auto_xfer_cfg_reg; + u8 auto_xfer_ctl_reg; + u8 auto_xfer_sts_reg; + u8 dcvs_sw_reg; + u8 gfmux_cfg_reg; + u8 write_ctl_reg; + u8 write_sts_reg; + u32 tl_delay_val; + u32 acd_ctrl_val; + u32 softstart_val; + u32 ext_intf0_val; + u32 ext_intf1_val; + u32 auto_xfer_val; +}; + +/** + * struct qcom_cpufreq_hw_params - Operating State Manager (OSM) Parameters + * + * @volt_lut_val: Value composed of: virtual corner (vc) and voltage in mV. + * @freq_lut_val: Value composed of: core count, clock source and output + * frequency in MHz. + * @override_val: PLL parameters that the OSM uses to override the previous + * setting coming from the bootloader, or when uninitialized. + * @spare_val: Spare register, used by both this driver and the OSM HW + * to identify MEM-ACC levels in relation to virtual corners. + * + * This structure holds the parameters to write to the OSM registers for + * one "Virtual Corner" (VC), or one Performance State (p-state). + */ +struct qcom_cpufreq_hw_params { + u32 volt_lut_val; + u32 freq_lut_val; + u32 override_val; + u32 spare_val; +}; #define GT_IRQ_STATUS BIT(2) #define HZ_PER_KHZ 1000 +/** + * struct qcom_cpufreq_soc_data - SoC specific register offsets of the OSM + * + * @reg_enable: OSM enable status + * @reg_index: Index of the Virtual Corner + * @reg_freq_lut: Frequency Lookup Table + * @reg_freq_lut_src_mask: Frequency Lookup Table clock-source mask + * @reg_volt_lut: Voltage Lookup Table + * @reg_perf_state: Performance State request register + * @lut_row_size: Lookup Table row size + * @clk_hw_div: Divider for "alternate" OSM clock-source + * @uses_tz: OSM already set-up and protected by TrustZone + * @setup_regs: Register offsets for OSM setup + */ struct qcom_cpufreq_soc_data { u32 reg_enable; u32 reg_domain_state; u32 reg_dcvs_ctrl; + u32 reg_index; u32 reg_freq_lut; + u32 reg_freq_lut_src_mask; u32 reg_volt_lut; u32 reg_intr_clr; u32 reg_current_vote; u32 reg_perf_state; u8 lut_row_size; + u8 clk_hw_div; + bool uses_tz; + const struct qcom_cpufreq_soc_setup_data setup_regs; + const struct qcom_cpufreq_soc_acd_data acd_data; }; struct qcom_cpufreq_data { @@ -59,9 +282,17 @@ struct qcom_cpufreq_data { bool per_core_dcvs; }; +static const char *cprh_genpd_names[] = { "cprh", NULL }; static unsigned long cpu_hw_rate, xo_rate; static bool icc_scaling_enabled; +/** + * qcom_cpufreq_set_bw() - Set interconnect bandwidth + * @policy: CPUFreq policy structure + * @freq_khz: CPU Frequency in KHz + * + * Returns: Zero for success, otherwise negative value on errors + */ static int qcom_cpufreq_set_bw(struct cpufreq_policy *policy, unsigned long freq_khz) { @@ -83,6 +314,20 @@ static int qcom_cpufreq_set_bw(struct cpufreq_policy *policy, return ret; } +/** + * qcom_cpufreq_update_opp() - Update CPU OPP tables + * @policy: CPUFreq policy structure + * @freq_khz: CPU Frequency for OPP entry in KHz + * @volt: CPU Voltage for OPP entry in microvolts + * + * The CPU frequencies and voltages are being read from the Operating + * State Manager (OSM) and the related OPPs, read from DT, need to be + * updated to reflect what the hardware will set for each p-state. + * If there is no OPP table specified in DT, then this function will + * add dynamic ones. + * + * Returns: Zero for success, otherwise negative value on errors + */ static int qcom_cpufreq_update_opp(struct device *cpu_dev, unsigned long freq_khz, unsigned long volt) @@ -103,6 +348,17 @@ static int qcom_cpufreq_update_opp(struct device *cpu_dev, return dev_pm_opp_enable(cpu_dev, freq_hz); } +/** + * qcom_cpufreq_hw_target_index() - Set frequency/voltage + * @policy: CPUFreq policy structure + * @index: Performance state index to be set + * + * This function sends a request to the Operating State Manager + * to set a Performance State index, so, to set frequency and + * voltage for the target CPU/cluster. + * + * Returns: Always zero + */ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy, unsigned int index) { @@ -123,6 +379,12 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy, return 0; } +/** + * qcom_cpufreq_hw_get() - Get current Performance State from OSM + * @cpu: CPU number + * + * Returns: Current CPU/Cluster frequency or zero + */ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu) { struct qcom_cpufreq_data *data; @@ -161,6 +423,585 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy, return policy->freq_table[index].frequency; } +/** + * qcom_cpufreq_hw_boost_setup() - Sets up OSM boost timer registers + * @timer0_addr: Start of boost timer0 register group + * @len: Length (size) of "sub" registers in timer0 group + */ +static void qcom_cpufreq_hw_boost_setup(void __iomem *timer0_addr, u32 len) +{ + u32 val; + + /* timer_reg0 */ + val = FIELD_PREP(BOOST_TIMER_REG_LO, PLL_WAIT_LOCK_TIME_NS); + val |= FIELD_PREP(BOOST_TIMER_REG_HI, SAFE_FREQ_WAIT_NS); + writel(val, timer0_addr); + + /* timer_reg1 */ + val = FIELD_PREP(BOOST_TIMER_REG_LO, PLL_WAIT_LOCK_TIME_NS); + val |= FIELD_PREP(BOOST_TIMER_REG_HI, PLL_WAIT_LOCK_TIME_NS); + writel(val, timer0_addr + len); + + /* timer_reg2 */ + val = FIELD_PREP(BOOST_TIMER_REG_LO, DEXT_DECREMENT_WAIT_NS); + writel(val, timer0_addr + (2 * len)); +} + +/** + * qcom_cpufreq_gen_params() - Generate parameters to send to the hardware + * @cpu_dev: CPU device + * @data: SoC specific register offsets + * @hw_tbl: Pointer to return the array of parameters + * @apm_vc: APM Virtual Corner crossover number, returned to the caller + * @acc_vc: MEMACC Virtual Corner crossover number, returned to the caller + * @cpu_count: Number of CPUs in the frequency domain + * @num_entries: Number of allocated (and filled) elements in the table, + * returned to the caller + * + * This function allocates a 'qcom_cpufreq_hw_params' parameters table, + * fills it and returns it to the consumer, ready to get sent to the HW. + * Since the APM threshold is just one + * Freeing the table after usage is left to the caller. + * + * Returns: Zero for success, otherwise negative value on errors. + */ +static int qcom_cpufreq_gen_params(struct device *cpu_dev, + struct qcom_cpufreq_data *data, + struct qcom_cpufreq_hw_params **hw_tbl, + int *apm_vc, int *acc_vc, int cpu_count, + u8 *num_entries) +{ + struct device **genpd_cpr_vdev; + struct platform_device *pdev = cpufreq_get_driver_data(); + const struct qcom_cpufreq_soc_data *soc_data = data->soc_data; + struct cpr_ext_data *cpr_data; + struct dev_pm_opp *genpd_opp; + unsigned long rate; + int apm_uV, acc_uV, i, gpd_opp_cnt, ret = 0; + + ret = devm_pm_opp_attach_genpd(cpu_dev, cprh_genpd_names, &genpd_cpr_vdev); + if (ret) { + dev_err(&pdev->dev, "Could not attach to pm_domain: %d\n", ret); + return ret; + } + + if (IS_ERR_OR_NULL(*genpd_cpr_vdev)) + return -EINVAL; + + /* + * In the CPR3 driver we have assigned data to the genpd newly created + * virtual device: this contains MEMACC and APM thresholds, as passing + * them through OPPs would be an API abuse. + */ + cpr_data = dev_get_drvdata(*genpd_cpr_vdev); + if (cpr_data == NULL) { + dev_err(&pdev->dev, "Cannot get CPR data\n"); + return -ENODATA; + } + + /* Get the count of available OPPs coming from the power domain */ + gpd_opp_cnt = dev_pm_opp_get_opp_count(cpu_dev); + if (gpd_opp_cnt < 2) { + ret = gpd_opp_cnt > 0 ? -EINVAL : gpd_opp_cnt; + goto detach_gpd; + } + + /* If we get no APM voltage, the system is going to be unstable */ + apm_uV = cpr_data->apm_threshold_uV; + if (apm_uV <= 0) { + ret = -EINVAL; + goto detach_gpd; + } + + /* + * Set apm_vc to a less than zero value: this is used later in the + * logic making sure that we're returning the right virtual corner + * for APM switch. + */ + *apm_vc = -1; + + /* + * Get the ACC threshold voltage: this is optional and not every + * SoC, or every SoC version, or every binning, needs it. + */ + if (cpr_data->mem_acc_threshold_uV <= 0) { + acc_uV = INT_MAX; + *acc_vc = U8_MAX; + } else { + acc_uV = cpr_data->mem_acc_threshold_uV; + *acc_vc = -1; + } + + *hw_tbl = devm_kmalloc_array(&pdev->dev, gpd_opp_cnt, + sizeof(**hw_tbl), GFP_KERNEL); + if (!hw_tbl) { + ret = -ENOMEM; + goto detach_gpd; + } + + for (i = 0, rate = 1000; i <= gpd_opp_cnt ; rate++, i++) { + struct qcom_cpufreq_hw_params *entry = *hw_tbl + i; + struct device_node *np; + u32 pll_div, millivolts, f_src; + + /* + * Find the next enabled OPP's frequency (ignores APM/ACC). + * + * We expect to get an error when we try to go past the last + * defined frequency, so we quit the loop gracefully without + * signaling any error, as this is the expected behavior. + */ + genpd_opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate); + if (IS_ERR(genpd_opp)) + break; + + /* Get mandatory and optional properties from the OPP DT */ + np = dev_pm_opp_get_of_node(genpd_opp); + if (!np) { + ret = -ENOENT; + goto detach_gpd; + } + + if (of_property_read_u32(np, "qcom,pll-override", + &entry->override_val)) { + ret = -EINVAL; + of_node_put(np); + goto detach_gpd; + } + + if (of_property_read_u32(np, "qcom,spare-data", + &entry->spare_val)) + entry->spare_val = 0; + + if (of_property_read_u32(np, "qcom,pll-div", &pll_div)) + pll_div = 0; + + of_node_put(np); + + /* Get voltage in microvolts, then convert to millivolts */ + millivolts = dev_pm_opp_get_voltage(genpd_opp); + if (millivolts >= apm_uV && *apm_vc < 0) + *apm_vc = i; + if (millivolts >= acc_uV && *acc_vc < 0) + *acc_vc = i; + + millivolts /= 1000; + + if (millivolts < 150 || millivolts > 1400) { + dev_err(&pdev->dev, + "Read invalid voltage: %u.\n", millivolts); + return -EINVAL; + } + + /* In the OSM firmware, "Virtual Corner" levels start from 0 */ + entry->volt_lut_val = FIELD_PREP(LUT_VOLT_VC, i); + entry->volt_lut_val |= FIELD_PREP(LUT_VOLT, millivolts); + + /* + * Only the first frequency has alternate source, as it is + * always that one that is used for low power idle states. + */ + f_src = i ? 1 : 0; + f_src <<= ffs(soc_data->reg_freq_lut_src_mask) - 1; + entry->freq_lut_val = f_src | div_u64(rate, xo_rate); + entry->freq_lut_val |= FIELD_PREP(LUT_CORE_COUNT, cpu_count); + + /* + * PLL divider is not always 0 and there is no way to determine + * it automatically, as setting this value higher than DIV1 + * will make the OSM HW to effectively set the PLL at 2-4x + * the CPU frequency and then divide the CPU clock by this div, + * so this value is effectively used as both a multiplier and + * divider. + * This value cannot be calculated because it depends on + * manual calibration and is (most probably) used to choose + * a PLL frequency that gives the least possible jitter. + */ + entry->freq_lut_val |= FIELD_PREP(LUT_PLL_DIV, pll_div); + + dev_dbg(&pdev->dev, + "[%d] freq=0x%x volt=0x%x override=0x%x spare=0x%x\n", + i, entry->freq_lut_val, entry->volt_lut_val, + entry->override_val, entry->spare_val); + dev_pm_opp_put(genpd_opp); + genpd_opp = NULL; + } + + /* + * If we've got a customized mem-acc corner but we couldn't + * find any suitable crossover, or the corner is less than + * the minimum amount of required corners for mem-acc scaling, + * the values are not valid, hence fall back to LUT values. + */ + if (acc_uV != INT_MAX && *acc_vc < SEQ_MEM_ACC_MAX_LEVELS - 1) { + dev_dbg(&pdev->dev, + "MEM-ACC corner: invalid values VC%d %duV\n", + *acc_vc, acc_uV); + *acc_vc = U8_MAX; + } + + /* + * If we have probed less params than what we need, then the + * OPP table that we got from the genpd is malformed for some + * reason: in this case, do not apply the table to the HW. + */ + if (i < gpd_opp_cnt) { + dev_err(&pdev->dev, "Got bad OPP table from power domain.\n"); + ret = -EINVAL; + goto detach_gpd; + } + *num_entries = i; + +detach_gpd: + return ret; +} + +static inline u32 qcom_cpufreq_acd_regbit(u8 acd_reg_offset) +{ + return BIT(acd_reg_offset / 4); +} + +static int qcom_cpufreq_hw_acd_write_autoxfer(struct qcom_cpufreq_data *data, + void __iomem *acd_base, u32 val) +{ + const struct qcom_cpufreq_soc_data *sdata = data->soc_data; + const struct qcom_cpufreq_soc_acd_data *aregs = &sdata->acd_data; + u32 regval = 0; + + writel(val, acd_base + aregs->auto_xfer_cfg_reg); + + /* (Clear, then) Set AUTOXFER START */ + writel(0, acd_base + aregs->auto_xfer_reg); + writel(1, acd_base + aregs->auto_xfer_reg); + + /* Poll for status: if the first bit is set the transfer is done. */ + return readl_poll_timeout(acd_base + aregs->auto_xfer_sts_reg, regval, + regval & BIT(0), 1, 3); +} + +static int qcom_cpufreq_hw_acd_write_xfer(struct qcom_cpufreq_data *data, + void __iomem *acd_base, u8 reg, + u32 val) +{ + const struct qcom_cpufreq_soc_data *sdata = data->soc_data; + const struct qcom_cpufreq_soc_acd_data *aregs = &sdata->acd_data; + u32 regval = 0; + + /* Write to the register, then initiate manual transfer */ + writel(val, acd_base + reg); + + /* Clear write control register */ + writel(0, acd_base + aregs->write_ctl_reg); + + regval = (reg / 4) << ACD_WRITE_CTL_SELECT_SHIFT; + regval |= ACD_WRITE_CTL_UPDATE_EN; + writel(regval, acd_base + aregs->write_ctl_reg); + + /* Wait until ACD Local Transfer is done */ + return readl_poll_timeout(acd_base + aregs->write_sts_reg, regval, + regval & qcom_cpufreq_acd_regbit(reg), 1, 3); +} + +/** + * qcom_cpufreq_hw_acd_init() - Initialize ACD params in the OSM + * @cpu_dev: CPU device + * @policy: CPUFreq policy structure + * @index: Instance number (CPU cluster number) + * + * On some SoCs it is required to send the ACD configuration parameters + * to the OSM. This function takes the parameters from the SoC specific + * configuration and writes them only if a "osm-acdN" iospace has been + * declared (hence, it's present). + * + * Returns: Zero for success, otherwise negative number on error. + */ +static int qcom_cpufreq_hw_acd_init(struct device *cpu_dev, + struct cpufreq_policy *policy, + int index) +{ + struct platform_device *pdev = cpufreq_get_driver_data(); + struct qcom_cpufreq_data *ddata = policy->driver_data; + const struct qcom_cpufreq_soc_data *sdata = ddata->soc_data; + const struct qcom_cpufreq_soc_acd_data *aregs = &sdata->acd_data; + char acd_resname[] = "osm-acdX"; + void __iomem *acd_base; + u32 rmask; + int ret; + + snprintf(acd_resname, sizeof(acd_resname), "osm-acd%d", index); + + acd_base = devm_platform_ioremap_resource_byname(pdev, acd_resname); + if (IS_ERR(acd_base)) { + dev_vdbg(cpu_dev, "Skipping ACD initialization.\n"); + return 0; + } + + writel(aregs->tl_delay_val, acd_base + aregs->tl_delay_reg); + writel(aregs->acd_ctrl_val, acd_base + aregs->acd_ctrl_reg); + writel(aregs->softstart_val, acd_base + aregs->softstart_reg); + writel(aregs->ext_intf0_val, acd_base + aregs->ext_intf_reg); + writel(aregs->auto_xfer_val, acd_base + aregs->auto_xfer_ctl_reg); + + rmask = qcom_cpufreq_acd_regbit(aregs->acd_ctrl_reg) | + qcom_cpufreq_acd_regbit(aregs->tl_delay_reg) | + qcom_cpufreq_acd_regbit(aregs->softstart_reg) | + qcom_cpufreq_acd_regbit(aregs->ext_intf_reg); + ret = qcom_cpufreq_hw_acd_write_autoxfer(ddata, acd_base, rmask); + if (ret) + return ret; + + /* Switch CPUSS clock source to ACD clock */ + ret = qcom_cpufreq_hw_acd_write_xfer(ddata, acd_base, + aregs->gfmux_cfg_reg, 1); + if (ret) + return ret; + + /* (Set, then) Clear DCVS_SW */ + ret = qcom_cpufreq_hw_acd_write_xfer(ddata, acd_base, + aregs->dcvs_sw_reg, 1); + if (ret) + return ret; + ret = qcom_cpufreq_hw_acd_write_xfer(ddata, acd_base, + aregs->dcvs_sw_reg, 0); + if (ret) + return ret; + + /* Wait for clock switch time */ + udelay(1); + + /* Program the final ACD external interface */ + ret = qcom_cpufreq_hw_acd_write_xfer(ddata, acd_base, + aregs->ext_intf_reg, + aregs->ext_intf1_val); + if (ret) + return ret; + + /* Initiate transfer of the final ACD value */ + rmask |= qcom_cpufreq_acd_regbit(aregs->gfmux_cfg_reg); + writel(rmask, acd_base + aregs->auto_xfer_cfg_reg); + + /* Wait for ACD to stabilize. Same wait as the OSM boot time... */ + udelay(OSM_BOOT_TIME_US); + return 0; +} + +/** + * qcom_cpufreq_hw_write_lut() - Write Lookup Table params to the OSM + * @cpu_dev: CPU device + * @policy: CPUFreq policy structure + * @cpu_count: Number of CPUs in the frequency domain + * @index: Instance number (CPU cluster number) + * + * Program all the Lookup Table (LUT) entries and related thresholds + * to the Operating State Manager on platforms where the same hasn't + * been done already by the bootloader or TrustZone before booting + * the operating system's kernel; + * On these platforms, write access to the OSM is (obviously) not + * blocked by the hypervisor. + * + * Returns: Zero for success, otherwise negative number on error. + */ +static int qcom_cpufreq_hw_write_lut(struct device *cpu_dev, + struct cpufreq_policy *policy, + int cpu_count, int index) +{ + struct platform_device *pdev = cpufreq_get_driver_data(); + struct qcom_cpufreq_data *ddata = policy->driver_data; + const struct qcom_cpufreq_soc_data *sdata = ddata->soc_data; + const struct qcom_cpufreq_soc_setup_data *sregs = &sdata->setup_regs; + struct qcom_cpufreq_hw_params *hw_tbl; + struct resource *osm_rsrc; + char osm_resname[] = "osm-domainX"; + u32 sreg, seq_addr, acc_lval = 0, last_spare = 1; + u8 num_entries = 0; + int apm_vc = INT_MAX, acc_vc = U8_MAX, acc_idx = 0; + int acc_val[SEQ_MEM_ACC_MAX_LEVELS], i, ret; + + snprintf(osm_resname, sizeof(osm_resname), "osm-domain%d", index); + + /* + * On some SoCs the OSM is not getting programmed from bootloader + * and needs to be done here: in this case, we need to retrieve + * the base physical address for the "Sequencer", so we will get + * the OSM base phys and apply the sequencer offset. + * + * Note: We are not remapping this iospace because we are really + * sending the physical address through SCM calls later. + */ + osm_rsrc = platform_get_resource_byname(pdev, IORESOURCE_MEM, osm_resname); + if (!osm_rsrc) + return -ENODEV; + + seq_addr = osm_rsrc->start + sregs->reg_osm_sequencer; + + ret = qcom_cpufreq_gen_params(cpu_dev, ddata, &hw_tbl, &apm_vc, + &acc_vc, cpu_count, &num_entries); + if (ret) + return ret; + + /* If we get less than 2 entries, scaling doesn't make sense */ + if (num_entries < 2) { + dev_err(&pdev->dev, "Not enough LUT entries found (%u)\n", num_entries); + return -EINVAL; + } + + for (i = 0; i < LUT_MAX_ENTRIES; i++) { + struct qcom_cpufreq_hw_params *entry; + int pos = i * sdata->lut_row_size; + + /* + * If we have reached the end of the params table, write + * the last valid entry until the end of the OSM table. + */ + if (i < num_entries) + entry = &hw_tbl[i]; + else + entry = &hw_tbl[num_entries - 1]; + + writel(i, ddata->base + sdata->reg_index + pos); + writel(entry->volt_lut_val, ddata->base + sdata->reg_volt_lut + pos); + writel(entry->freq_lut_val, ddata->base + sdata->reg_freq_lut + pos); + writel(entry->override_val, ddata->base + sregs->reg_override + pos); + writel(entry->spare_val, ddata->base + sregs->reg_spare + pos); + + dev_dbg(cpu_dev, "Writing [%d] v:0x%x f:0x%x ovr:0x%x s:0x%x\n", i, + entry->volt_lut_val, entry->freq_lut_val, + entry->override_val, entry->spare_val); + + /* + * MEM-ACC Virtual Corner threshold voltage: this gets set + * as the pairs of corners in which there is a transition + * between one MEM-ACC level and the next one. + * + * Notes: The spare_val can never be zero; + * The first spare_val is always 1; + * The maximum number of pairs is two (four registers). + * + * Example: (C = Corner Level - M = MEM-ACC Level) + * C0 M1 - C1 M1 - C2 M2 - C3 M2 - C4 M2 - C5 M3 + * Pairs: 1-2, 4-5 + */ + if (entry->spare_val <= last_spare || + acc_idx >= SEQ_MEM_ACC_MAX_LEVELS - 1) + continue; + + /* Standard mem-acc pairs using spare_val LUT crossovers */ + last_spare = entry->spare_val; + acc_val[acc_idx] = i - 1; + acc_idx++; + acc_val[acc_idx] = i; + acc_idx++; + } + + /* Sanity check: we *must* have two mem-acc crossovers (four values) */ + if (acc_idx < SEQ_MEM_ACC_MAX_LEVELS - 1) + return -EINVAL; + + /* + * Customized mem-acc corners, if any; in this case, the last corner + * in the external (CPRh) LUT is this one, placed after the APM one. + */ + if (acc_vc > 0 && acc_vc != U8_MAX) { + sreg = SEQUENCER_REG(seq_addr, SEQ_MEM_ACC_CROSSOVER_VC); + ret = qcom_scm_io_writel(sreg, num_entries + 1); + if (ret) + return ret; + + /* + * At the price of very-slightly higher power consumption, + * switch the ACC at one corner lower than what we've found, + * as this seems to be needed on at least some MSM8998 chips + * to achieve full system stability + */ + acc_vc--; + + /* Change only if we have to move the corner down */ + if (acc_vc < acc_val[3]) { + acc_val[2] = acc_vc - 1; + acc_val[3] = acc_vc; + } + + /* If needed, sanitize previously stored vals from the LUT */ + if (acc_val[2] <= acc_val[1]) + acc_val[1] = acc_val[2] - 1; + if (acc_val[1] <= acc_val[0]) + acc_val[0] = acc_val[1] - 1; + } + + for (i = 0; i < SEQ_MEM_ACC_MAX_LEVELS; i++) { + ret = qcom_scm_io_writel(SEQ_MEMACC_REG(seq_addr, i), acc_val[i]); + if (ret) + return ret; + } + dev_dbg(cpu_dev, "Wrote MEM-ACC Pairs: [%u-%u] [%u-%u]\n", + acc_val[0], acc_val[1], acc_val[2], acc_val[3]); + + /* + * Program the L_VAL of the first corner requesting MEM-ACC + * voltage level 3 to the right sequencer register + */ + acc_lval = FIELD_GET(LUT_L_VAL, hw_tbl[acc_val[3]].freq_lut_val); + ret = qcom_scm_io_writel(SEQUENCER_REG(seq_addr, SEQ_MEM_ACC_LVAL), acc_lval); + if (ret) { + dev_dbg(cpu_dev, "Cannot send memacc l_val\n"); + return ret; + } + dev_dbg(cpu_dev, "MEM-ACC L-Val is %u\n", acc_lval); + + /* + * Array Power Mux threshold level: the first virtual corner + * that requires a switch sequence of the APM from MX to APC. + */ + if (apm_vc == INT_MAX) + apm_vc = LUT_MAX_ENTRIES - 1; + + /* + * APM crossover virtual corner refers to CPRh: there, the APM corner + * is always appended to the table (so, at the end of it, right after + * the cluster dvfs entries). + */ + writel(num_entries, ddata->base + sregs->reg_seq1); + ret = qcom_scm_io_writel(SEQUENCER_REG(seq_addr, SEQ_APM_CROSSOVER_VC), num_entries); + if (ret) + return ret; + + ret = qcom_scm_io_writel(SEQUENCER_REG(seq_addr, SEQ_APM_THRESH_VC), apm_vc); + if (ret) + return ret; + + ret = qcom_scm_io_writel(SEQUENCER_REG(seq_addr, SEQ_APM_THRESH_PREVC), apm_vc - 1); + if (ret) + return ret; + + ret = qcom_scm_io_writel(SEQUENCER_REG(seq_addr, SEQ_APM_PARAM), + (0x39 | apm_vc << 6)); + if (ret) + return ret; + dev_dbg(cpu_dev, "Wrote APM Pair: [%u-%u]\n", apm_vc - 1, apm_vc); + + /* + * We succeeded! Dispose of the table that got allocated during + * qcom_cpufreq_gen_params, as that contains parameters that are + * relevant only to the context of OSM programming, which is done + * only once. + */ + if (hw_tbl) + devm_kfree(&pdev->dev, hw_tbl); + + return 0; +} + +/** + * qcom_cpufreq_hw_read_lut() - Read Lookup Table from the OSM + * @cpu_dev: CPU device + * @policy: CPUFreq policy structure + * + * The Operating State Manager Lookup Table can always be read, even + * in case it was pre-programmed by the bootloader or by TrustZone. + * Read the LUT from it in order to build OPPs containing DVFS info. + * + * Returns: Zero for success, otherwise negative number on errors. + */ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, struct cpufreq_policy *policy) { @@ -198,14 +1039,16 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, } for (i = 0; i < LUT_MAX_ENTRIES; i++) { - data = readl_relaxed(drv_data->base + soc_data->reg_freq_lut + - i * soc_data->lut_row_size); - src = FIELD_GET(LUT_SRC, data); + data = readl(drv_data->base + soc_data->reg_freq_lut + + i * soc_data->lut_row_size); + src = data & soc_data->reg_freq_lut_src_mask; + src >>= ffs(soc_data->reg_freq_lut_src_mask) - 1; + lval = FIELD_GET(LUT_L_VAL, data); core_count = FIELD_GET(LUT_CORE_COUNT, data); - data = readl_relaxed(drv_data->base + soc_data->reg_volt_lut + - i * soc_data->lut_row_size); + data = readl(drv_data->base + soc_data->reg_volt_lut + + i * soc_data->lut_row_size); volt = FIELD_GET(LUT_VOLT, data) * 1000; if (src) @@ -243,8 +1086,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, prev->frequency = prev_freq; prev->flags = CPUFREQ_BOOST_FREQ; } else { - dev_warn(cpu_dev, "failed to update OPP for freq=%d\n", - freq); + dev_warn(cpu_dev, "can't update OPP for freq=%u\n", freq); } } @@ -261,10 +1103,18 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, return 0; } -static void qcom_get_related_cpus(int index, struct cpumask *m) +/* + * qcom_get_related_cpus - Get mask of CPUs in the same frequency domain + * @index: CPU number + * @m: Returned CPU mask + * + * Returns: Count of CPUs inserted in the cpumask or negative number for error. + */ +static int qcom_get_related_cpus(int index, struct cpumask *m) { struct device_node *cpu_np; struct of_phandle_args args; + int count = 0; int cpu, ret; for_each_possible_cpu(cpu) { @@ -273,15 +1123,18 @@ static void qcom_get_related_cpus(int index, struct cpumask *m) continue; ret = of_parse_phandle_with_args(cpu_np, "qcom,freq-domain", - "#freq-domain-cells", 0, - &args); + "#freq-domain-cells", 0, &args); of_node_put(cpu_np); if (ret < 0) continue; - if (index == args.args[0]) + if (index == args.args[0]) { cpumask_set_cpu(cpu, m); + count++; + } } + + return count > 0 ? count : -EINVAL; } static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) @@ -374,10 +1227,75 @@ static const struct qcom_cpufreq_soc_data qcom_soc_data = { .reg_enable = 0x0, .reg_dcvs_ctrl = 0xbc, .reg_freq_lut = 0x110, + .reg_freq_lut_src_mask = LUT_SRC_845, .reg_volt_lut = 0x114, .reg_current_vote = 0x704, .reg_perf_state = 0x920, .lut_row_size = 32, + .clk_hw_div = 2, + .uses_tz = true, +}; + +static const struct qcom_cpufreq_soc_data msm8998_soc_data = { + .reg_enable = 0x4, + .reg_index = 0x150, + .reg_freq_lut = 0x154, + .reg_freq_lut_src_mask = LUT_SRC_8998, + .reg_volt_lut = 0x158, + .reg_perf_state = 0xf10, + .lut_row_size = 32, + .clk_hw_div = 1, + .uses_tz = false, + .setup_regs = { + /* Physical offset for sequencer scm calls */ + .reg_osm_sequencer = 0x300, + + /* Frequency domain offsets */ + .reg_override = 0x15c, + .reg_spare = 0x164, + .reg_cc_zero_behav = 0x0c, + .reg_spm_cc_hyst = 0x1c, + .reg_spm_cc_dcvs_dis = 0x20, + .reg_spm_core_ret_map = 0x24, + .reg_llm_freq_vote_hyst = 0x2c, + .reg_llm_volt_vote_hyst = 0x30, + .reg_llm_intf_dcvs_dis = 0x34, + .reg_seq1 = 0x48, + .reg_pdn_fsm_ctrl = 0x70, + .reg_cc_boost_timer = 0x74, + .reg_dcvs_boost_timer = 0x84, + .reg_ps_boost_timer = 0x94, + .boost_timer_reg_len = 0x4, + .reg_boost_sync_delay = 0xa0, + .reg_droop_ctrl = 0xa4, + .reg_droop_release_ctrl = 0xa8, + .reg_droop_unstall_ctrl = 0xac, + .reg_droop_wait_release_ctrl = 0xb0, + .reg_droop_timer_ctrl = 0xb8, + .reg_droop_sync_delay = 0xbc, + .reg_pll_override = 0xc0, + .reg_cycle_counter = 0xf00, + }, + .acd_data = { + .acd_ctrl_reg = 0x4, + .tl_delay_reg = 0x8, + .softstart_reg = 0x28, + .ext_intf_reg = 0x30, + .dcvs_sw_reg = 0x34, + .gfmux_cfg_reg = 0x3c, + .auto_xfer_cfg_reg = 0x80, + .auto_xfer_reg = 0x84, + .auto_xfer_ctl_reg = 0x88, + .auto_xfer_sts_reg = 0x8c, + .write_ctl_reg = 0x90, + .write_sts_reg = 0x94, + .tl_delay_val = 38417, + .acd_ctrl_val = 0x2b5ffd, + .softstart_val = 0x501, + .ext_intf0_val = 0x2cf9ae8, + .ext_intf1_val = 0x2cf9afe, + .auto_xfer_val = 0x15, + }, }; static const struct qcom_cpufreq_soc_data epss_soc_data = { @@ -385,14 +1303,18 @@ static const struct qcom_cpufreq_soc_data epss_soc_data = { .reg_domain_state = 0x20, .reg_dcvs_ctrl = 0xb0, .reg_freq_lut = 0x100, + .reg_freq_lut_src_mask = LUT_SRC_845, .reg_volt_lut = 0x200, .reg_intr_clr = 0x308, .reg_perf_state = 0x320, .lut_row_size = 4, + .clk_hw_div = 2, + .uses_tz = true, }; static const struct of_device_id qcom_cpufreq_hw_match[] = { { .compatible = "qcom,cpufreq-hw", .data = &qcom_soc_data }, + { .compatible = "qcom,cpufreq-hw-8998", .data = &msm8998_soc_data }, { .compatible = "qcom,cpufreq-epss", .data = &epss_soc_data }, {} }; @@ -472,6 +1394,130 @@ static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) free_irq(data->throttle_irq, data); } +/** + * qcom_cpufreq_hw_osm_setup() - Setup and enable the OSM + * @cpu_dev: CPU device + * @policy: CPUFreq policy structure + * @cpu_count: Number of CPUs in the frequency domain + * + * On some platforms, the Operating State Manager (OSM) is not getting + * programmed by the bootloader, nor by TrustZone before booting the OS + * and its register space is not write-protected by the hypervisor. + * In this case, to achieve CPU DVFS, it is needed to program it from + * the OS itself, which includes setting LUT and all the various tunables + * that are required for it to manage the CPU frequencies and voltages + * on its own. + * Calling this function on a platform that had the OSM set-up by TZ + * will result in a hypervisor fault with system reboot in most cases. + * + * Returns: Zero for success, otherwise negative number on errors. + */ +static int qcom_cpufreq_hw_osm_setup(struct device *cpu_dev, + struct cpufreq_policy *policy, + int cpu_count, int index) +{ + struct qcom_cpufreq_data *drv_data = policy->driver_data; + const struct qcom_cpufreq_soc_setup_data *setup_regs; + u32 val; + int ret; + + ret = qcom_cpufreq_hw_write_lut(cpu_dev, policy, cpu_count, index); + if (ret) + return ret; + + setup_regs = &drv_data->soc_data->setup_regs; + + /* Set OSM to XO clock ratio and use XO edge for the cycle counter */ + val = FIELD_PREP(CYCLE_COUNTER_CLK_RATIO, OSM_XO_RATIO_VAL); + val |= CYCLE_COUNTER_USE_XO_EDGE; + + /* Enable the CPU cycle counter */ + val |= BIT(0); + writel(val, drv_data->base + setup_regs->reg_cycle_counter); + + /* CoreCount DCVS Policy: Wait time for frequency inc/decrement */ + val = FIELD_PREP(HYSTERESIS_UP_MASK, HYSTERESIS_CC_NS); + val |= FIELD_PREP(HYSTERESIS_DN_MASK, HYSTERESIS_CC_NS); + writel(val, drv_data->base + setup_regs->reg_spm_cc_hyst); + + /* Set the frequency index 0 and override for cluster power collapse */ + writel(BIT(0), drv_data->base + setup_regs->reg_cc_zero_behav); + + /* Treat cores in retention as active */ + writel(0, drv_data->base + setup_regs->reg_spm_core_ret_map); + + /* Enable CoreCount based DCVS */ + writel(0, drv_data->base + setup_regs->reg_spm_cc_dcvs_dis); + + /* CoreCount DCVS-LLM Policy: Wait time for frequency inc/decrement */ + val = FIELD_PREP(HYSTERESIS_UP_MASK, HYSTERESIS_LLM_NS); + val |= FIELD_PREP(HYSTERESIS_DN_MASK, HYSTERESIS_LLM_NS); + writel(val, drv_data->base + setup_regs->reg_llm_freq_vote_hyst); + + /* CoreCount DCVS-LLM Policy: Wait time for voltage inc/decrement */ + val = FIELD_PREP(HYSTERESIS_UP_MASK, HYSTERESIS_LLM_NS); + val |= FIELD_PREP(HYSTERESIS_DN_MASK, HYSTERESIS_LLM_NS); + writel(val, drv_data->base + setup_regs->reg_llm_volt_vote_hyst); + + /* Enable LLM frequency+voltage voting */ + writel(0, drv_data->base + setup_regs->reg_llm_intf_dcvs_dis); + + /* Setup Boost FSM Timers */ + qcom_cpufreq_hw_boost_setup(drv_data->base + setup_regs->reg_cc_boost_timer, + setup_regs->boost_timer_reg_len); + qcom_cpufreq_hw_boost_setup(drv_data->base + setup_regs->reg_dcvs_boost_timer, + setup_regs->boost_timer_reg_len); + qcom_cpufreq_hw_boost_setup(drv_data->base + setup_regs->reg_ps_boost_timer, + setup_regs->boost_timer_reg_len); + + /* PLL signal timing control for Boost */ + writel(BOOST_SYNC_DELAY, drv_data->base + setup_regs->reg_boost_sync_delay); + + /* Setup WFx and PC/RET droop unstall */ + val = FIELD_PREP(DROOP_TIMER1, DROOP_TIMER_NS); + val |= FIELD_PREP(DROOP_TIMER0, DROOP_TIMER_NS); + writel(val, drv_data->base + setup_regs->reg_droop_unstall_ctrl); + + /* Setup WFx and PC/RET droop wait-to-release */ + val = FIELD_PREP(DROOP_TIMER1, DROOP_WAIT_RELEASE_TIMER_NS); + val |= FIELD_PREP(DROOP_TIMER0, DROOP_WAIT_RELEASE_TIMER_NS); + writel(val, drv_data->base + setup_regs->reg_droop_wait_release_ctrl); + + /* PLL signal timing control for Droop */ + writel(1, drv_data->base + setup_regs->reg_droop_sync_delay); + + /* Setup DCVS timers */ + writel(DROOP_RELEASE_TIMER_NS, + drv_data->base + setup_regs->reg_droop_release_ctrl); + writel(DROOP_TIMER_NS, drv_data->base + setup_regs->reg_droop_timer_ctrl); + + /* Setup Droop control */ + val = readl(drv_data->base + setup_regs->reg_droop_ctrl); + val |= DROOP_CTRL_VAL; + writel(val, drv_data->base + setup_regs->reg_droop_ctrl); + + /* Enable CC-Boost, DCVS-Boost, PS-Boost, WFx, PC/RET, DCVS FSM */ + val = readl(drv_data->base + setup_regs->reg_pdn_fsm_ctrl); + val |= CC_BOOST_EN | PS_BOOST_EN | DCVS_BOOST_EN; + val |= WFX_DROOP_EN | PC_RET_EXIT_DROOP_EN | DCVS_DROOP_EN; + writel(val, drv_data->base + setup_regs->reg_pdn_fsm_ctrl); + + /* Enable PLL Droop Override */ + val = PLL_OVERRIDE_DROOP_EN; + writel(val, drv_data->base + setup_regs->reg_pll_override); + + /* Initialize the Adaptive Clock Distribution */ + ret = qcom_cpufreq_hw_acd_init(cpu_dev, policy, index); + if (ret) + return ret; + + /* We're ready: enable the OSM and give it time to boot (5uS) */ + writel(1, drv_data->base + drv_data->soc_data->reg_enable); + udelay(OSM_BOOT_TIME_US); + + return 0; +} + static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) { struct platform_device *pdev = cpufreq_get_driver_data(); @@ -482,7 +1528,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) struct resource *res; void __iomem *base; struct qcom_cpufreq_data *data; - int ret, index; + char fdom_resname[] = "freq-domainX"; + unsigned int transition_latency; + int cpu_count, index, ret; cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { @@ -503,7 +1551,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) index = args.args[0]; - res = platform_get_resource(pdev, IORESOURCE_MEM, index); + snprintf(fdom_resname, sizeof(fdom_resname), "freq-domain%d", index); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, fdom_resname); if (!res) { dev_err(dev, "failed to get mem resource %d\n", index); return -ENODEV; @@ -530,6 +1580,28 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) data->soc_data = of_device_get_match_data(&pdev->dev); data->base = base; data->res = res; + policy->driver_data = data; + + if (readl_relaxed(base + data->soc_data->reg_dcvs_ctrl) & 0x1) + data->per_core_dcvs = true; + + cpu_count = qcom_get_related_cpus(index, policy->cpus); + if (cpumask_empty(policy->cpus)) { + dev_err(dev, "Domain-%d failed to get related CPUs\n", index); + ret = -ENOENT; + goto error; + } + + policy->dvfs_possible_from_any_cpu = true; + if (!data->soc_data->uses_tz) { + ret = qcom_cpufreq_hw_osm_setup(cpu_dev, policy, + cpu_count, index); + if (ret) { + dev_err(dev, "Cannot setup the OSM for CPU%d: %d\n", + policy->cpu, ret); + goto error; + } + } /* HW should be in enabled state to proceed */ if (!(readl_relaxed(base + data->soc_data->reg_enable) & 0x1)) { @@ -538,19 +1610,6 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) goto error; } - if (readl_relaxed(base + data->soc_data->reg_dcvs_ctrl) & 0x1) - data->per_core_dcvs = true; - - qcom_get_related_cpus(index, policy->cpus); - if (cpumask_empty(policy->cpus)) { - dev_err(dev, "Domain-%d failed to get related CPUs\n", index); - ret = -ENOENT; - goto error; - } - - policy->driver_data = data; - policy->dvfs_possible_from_any_cpu = true; - ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy); if (ret) { dev_err(dev, "Domain-%d failed to read LUT\n", index); @@ -564,6 +1623,12 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) goto error; } + transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev); + if (!transition_latency) + transition_latency = CPUFREQ_ETERNAL; + + policy->cpuinfo.transition_latency = transition_latency; + if (policy_has_boost_freq(policy)) { ret = cpufreq_enable_boost_support(); if (ret) @@ -576,6 +1641,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) return 0; error: + policy->driver_data = NULL; kfree(data); unmap_base: iounmap(base); @@ -636,9 +1702,50 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = { static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev) { + const struct qcom_cpufreq_soc_data *soc_data; + struct device_node *pd_node; + struct platform_device *pd_dev; struct device *cpu_dev; struct clk *clk; - int ret; + int clk_div, ret; + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) + return -EPROBE_DEFER; + + soc_data = of_device_get_match_data(&pdev->dev); + if (!soc_data) + return -EINVAL; + + if (!soc_data->uses_tz) { + /* + * When the OSM is not pre-programmed from TZ, we will + * need to program the sequencer through SCM calls. + */ + if (!qcom_scm_is_available()) + return -EPROBE_DEFER; + + /* + * If there are no power-domains, OSM programming cannot be + * performed, as in that case, we wouldn't know where to take + * the params from... + */ + pd_node = of_parse_phandle(cpu_dev->of_node, "power-domains", 0); + if (!pd_node) { + ret = PTR_ERR(pd_node); + dev_err(cpu_dev, "power domain not found: %d\n", ret); + return ret; + } + + /* + * If the power domain device is not registered yet, then + * defer probing this driver until that is available. + */ + pd_dev = of_find_device_by_node(pd_node); + if (!pd_dev || !pd_dev->dev.driver || + !device_is_bound(&pd_dev->dev)) + return -EPROBE_DEFER; + } clk = clk_get(&pdev->dev, "xo"); if (IS_ERR(clk)) @@ -651,16 +1758,16 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev) if (IS_ERR(clk)) return PTR_ERR(clk); - cpu_hw_rate = clk_get_rate(clk) / CLK_HW_DIV; + clk_div = soc_data->clk_hw_div; + if (clk_div == 0) + clk_div++; + + cpu_hw_rate = clk_get_rate(clk) / clk_div; clk_put(clk); cpufreq_qcom_hw_driver.driver_data = pdev; /* Check for optional interconnect paths on CPU0 */ - cpu_dev = get_cpu_device(0); - if (!cpu_dev) - return -EPROBE_DEFER; - ret = dev_pm_opp_of_find_icc_paths(cpu_dev, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index ba1608effc0f..aacfaf1e54fb 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -42,7 +42,7 @@ int __drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj, { int ret; - WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb); + //WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb); mutex_lock(&dev->mode_config.idr_mutex); ret = idr_alloc(&dev->mode_config.object_idr, register_obj ? obj : NULL, @@ -237,10 +237,10 @@ void drm_object_attach_property(struct drm_mode_object *obj, if (obj->type == DRM_MODE_OBJECT_CONNECTOR) { - struct drm_connector *connector = obj_to_connector(obj); + /*struct drm_connector *connector = obj_to_connector(obj); WARN_ON(!dev->driver->load && - connector->registration_state == DRM_CONNECTOR_REGISTERED); + connector->registration_state == DRM_CONNECTOR_REGISTERED);*/ } else { WARN_ON(!dev->driver->load && dev->registered); } diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index c79502525963..cd29a68c5c2d 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -104,7 +104,7 @@ config DRM_MSM_DSI_14NM_PHY Choose this option if DSI PHY on 8996 is used on the platform. config DRM_MSM_DSI_10NM_PHY - bool "Enable DSI 10nm PHY driver in MSM DRM (used by SDM845)" + bool "Enable DSI 10nm PHY driver in MSM DRM (used by MSM8998/SDM845)" depends on DRM_MSM_DSI default y help diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 407f50a15faa..7f317a09a632 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -121,6 +121,48 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit msm_gpu_retire(gpu); } +static void a5xx_set_pagetable(struct a5xx_gpu *a5xx_gpu, + struct msm_ringbuffer *ring, struct msm_file_private *ctx) +{ + phys_addr_t ttbr; + u32 asid; + u64 memptr = rbmemptr(ring, ttbr0); + + if (ctx == a5xx_gpu->cur_ctx) + return; + + if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) + return; + + /* Execute the table update */ + OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 3); + OUT_RING(ring, CP_SMMU_TABLE_UPDATE_0_TTBR0_LO(lower_32_bits(ttbr))); + + OUT_RING(ring, + CP_SMMU_TABLE_UPDATE_1_TTBR0_HI(upper_32_bits(ttbr)) | + CP_SMMU_TABLE_UPDATE_1_ASID(asid)); + OUT_RING(ring, CP_SMMU_TABLE_UPDATE_2_CONTEXTIDR(0)); + + /* + * Write the new TTBR0 to the memstore. This is good for debugging. + */ + OUT_PKT7(ring, CP_MEM_WRITE, 4); + OUT_RING(ring, CP_MEM_WRITE_0_ADDR_LO(lower_32_bits(memptr))); + OUT_RING(ring, CP_MEM_WRITE_1_ADDR_HI(upper_32_bits(memptr))); + OUT_RING(ring, lower_32_bits(ttbr)); + OUT_RING(ring, (asid << 16) | upper_32_bits(ttbr)); + + /* + * And finally, trigger a uche flush to be sure there isn't anything + * lingering in that part of the GPU + */ + + OUT_PKT7(ring, CP_EVENT_WRITE, 1); + OUT_RING(ring, 0x31); + + a5xx_gpu->cur_ctx = ctx; +} + static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -151,13 +193,17 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) OUT_RING(ring, 1); /* Enable local preemption for finegrain preemption */ - OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); - OUT_RING(ring, 0x02); + //OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); + //OUT_RING(ring, 0x02); + OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1); + OUT_RING(ring, 0x01); /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */ OUT_PKT7(ring, CP_YIELD_ENABLE, 1); OUT_RING(ring, 0x02); + a5xx_set_pagetable(a5xx_gpu, ring, submit->queue->ctx); + /* Submit the commands */ for (i = 0; i < submit->nr_cmds; i++) { switch (submit->cmd[i].type) { @@ -942,6 +988,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu) a5xx_preempt_fini(gpu); gpu->nr_rings = 1; } + a5xx_gpu->cur_ctx = NULL; a5xx_preempt_hw_init(gpu); @@ -1697,6 +1744,20 @@ static uint32_t a5xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) return ring->memptrs->rptr = gpu_read(gpu, REG_A5XX_CP_RB_RPTR); } +static struct msm_gem_address_space * +a5xx_create_private_address_space(struct msm_gpu *gpu) +{ + struct msm_mmu *mmu; + + mmu = msm_iommu_pagetable_create(gpu->aspace->mmu); + + if (IS_ERR(mmu)) + return ERR_CAST(mmu); + + return msm_gem_address_space_create(mmu, + "gpu", 0x100000000ULL, 0x1ffffffffULL); +} + static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, @@ -1719,6 +1780,7 @@ static const struct adreno_gpu_funcs funcs = { .gpu_state_get = a5xx_gpu_state_get, .gpu_state_put = a5xx_gpu_state_put, .create_address_space = adreno_iommu_create_address_space, + .create_private_address_space = a5xx_create_private_address_space, .get_rptr = a5xx_get_rptr, }, .get_timestamp = a5xx_get_timestamp, diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h index c7187bcc5e90..781b759918e9 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h @@ -29,6 +29,7 @@ struct a5xx_gpu { struct msm_ringbuffer *cur_ring; struct msm_ringbuffer *next_ring; + struct msm_file_private *cur_ctx; struct drm_gem_object *preempt_bo[MSM_GPU_MAX_RINGS]; struct drm_gem_object *preempt_counters_bo[MSM_GPU_MAX_RINGS]; diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 8706bcdd1472..bb96e576d319 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -355,6 +355,11 @@ MODULE_FIRMWARE("qcom/a530_zap.mdt"); MODULE_FIRMWARE("qcom/a530_zap.b00"); MODULE_FIRMWARE("qcom/a530_zap.b01"); MODULE_FIRMWARE("qcom/a530_zap.b02"); +MODULE_FIRMWARE("qcom/a540_gpmu.fw2"); +MODULE_FIRMWARE("qcom/a540_zap.mdt"); +MODULE_FIRMWARE("qcom/a540_zap.b00"); +MODULE_FIRMWARE("qcom/a540_zap.b01"); +MODULE_FIRMWARE("qcom/a540_zap.b02"); MODULE_FIRMWARE("qcom/a630_sqe.fw"); MODULE_FIRMWARE("qcom/a630_gmu.bin"); MODULE_FIRMWARE("qcom/a630_zap.mbn"); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index b85b24bd3f53..69217f4be712 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -743,6 +743,7 @@ struct dpu_mdss_cfg { const struct dpu_mdp_cfg *mdp; u32 ctl_count; + bool ctl_no_start_read_quirk; const struct dpu_ctl_cfg *ctl; u32 sspp_count; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 3584f5ee6bb3..7505f861e674 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -94,7 +94,7 @@ static inline void dpu_hw_ctl_trigger_start(struct dpu_hw_ctl *ctx) static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx) { - return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0)); + return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0)) || ctx->ctl_no_start_read_quirk; } static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx) @@ -628,6 +628,7 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx, c->idx = idx; c->mixer_count = m->mixer_count; c->mixer_hw_caps = m->mixer; + c->ctl_no_start_read_quirk = m->ctl_no_start_read_quirk; return c; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index ac1544474022..b78bdbee44c0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -203,6 +203,7 @@ struct dpu_hw_ctl { u32 pending_flush_mask; u32 pending_intf_flush_mask; u32 pending_merge_3d_flush_mask; + bool ctl_no_start_read_quirk; /* ops */ struct dpu_hw_ctl_ops ops; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index e29796c4f27b..54fe351350d2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1072,6 +1072,10 @@ static int dpu_kms_hw_init(struct msm_kms *kms) goto power_error; } + if (of_property_read_bool(dpu_kms->pdev->dev.of_node, "qcom,ctl-no-start-read-quirk")) { + dpu_kms->catalog->ctl_no_start_read_quirk = true; + } + /* * Now we need to read the HW catalog and initialize resources such as * clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 08b015ea1b1e..b933b1ad013e 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -122,7 +122,7 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll, struct dsi_pll_confi pll_freq = pll->vco_current_rate; - divider = fref * 2; + divider = fref; multiplier = 1 << FRAC_BITS; dec_multiple = div_u64(pll_freq * multiplier, divider); @@ -440,12 +440,11 @@ static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, * 1. Assumes prescaler is disabled */ multiplier = 1 << FRAC_BITS; - pll_freq = dec * (ref_clk * 2); - tmp64 = (ref_clk * 2 * frac); + pll_freq = dec * ref_clk; + tmp64 = ref_clk * frac; pll_freq += div_u64(tmp64, multiplier); vco_rate = pll_freq; - pll_10nm->vco_current_rate = vco_rate; DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", pll_10nm->phy->id, (unsigned long)vco_rate, dec, frac); diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index ddf5f38e8731..0ec0991b8206 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -461,6 +461,36 @@ config DRM_PANEL_SAMSUNG_S6D27A1 This panel can be found in Samsung Galaxy Ace 2 GT-I8160 mobile phone. +config DRM_PANEL_SAMSUNG_S6E3FA5 + tristate "Samsung S6E3FA5 DSI command mode panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + help + Say Y here if you want to enable support for Samsung S6E3FA5 AMOLED + command mode panel as found in OnePlus 5 (2017) devices. The panel has a + FHD (1080x1920) resolution and uses 24 bit RGB per pixel. It provides a + MIPI DSI interface to the host and has a built-in LED backlight. + + To compile this driver as a module, choose M here: the module + will be called panel-samsung-s6e3fa5. + +config DRM_PANEL_SAMSUNG_S6E3FC1 + tristate "Samsung S6E3FC1 DSI command mode panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + help + Say Y here if you want to enable support for Samsung S6E3FC1 AMOLED + command mode panel as found in OnePlus 5T (2017) devices. The panel has a + FHD (1080x2160) resolution and uses 24 bit RGB per pixel. It provides a + MIPI DSI interface to the host and has a built-in LED backlight. + + To compile this driver as a module, choose M here: the module + will be called panel-samsung-s6e3fc1. + config DRM_PANEL_SAMSUNG_S6E3HA2 tristate "Samsung S6E3HA2 DSI video mode panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 5740911f637c..a1f5bf106104 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -45,6 +45,8 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D27A1) += panel-samsung-s6d27a1.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FA5) += panel-samsung-s6e3fa5.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FC1) += panel-samsung-s6e3fc1.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c b/drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c new file mode 100644 index 000000000000..e944c7a7035c --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c @@ -0,0 +1,351 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2021 Jami Kettunen + * Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include