Compare commits
129 commits
mainline/6
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b7263cccc | ||
|
|
22da203ef8 | ||
|
|
4f782f4c3f | ||
|
|
d23c7879c3 | ||
|
|
ae7254d494 | ||
|
|
38feeb3074 | ||
|
|
a8eef75016 | ||
|
|
9479a999eb | ||
|
|
7b4df030bf | ||
|
|
48f3cc5f01 | ||
|
|
a106139665 | ||
|
|
007c711d46 | ||
|
|
31fcc8d96d | ||
|
|
fa3def2129 | ||
|
|
f2922a7943 | ||
|
|
43f9c1b6df | ||
|
|
705df38a9e | ||
|
|
324c137044 | ||
|
|
fbfe0bb714 | ||
|
|
5c0b2f4545 | ||
|
|
3e22a6e8a3 | ||
|
|
ab047e6597 | ||
|
|
53da3375c4 | ||
|
|
246f4d6148 | ||
|
|
8b90216819 | ||
|
|
7cca9eb36d | ||
|
|
3ea414062d | ||
|
|
73e0c82858 | ||
|
|
39cd6b976d | ||
|
|
b408f19a4f | ||
|
|
35d1ed29cc | ||
|
|
158d9831bf | ||
|
|
8535dcd7c2 | ||
|
|
fdd5838e2b | ||
|
|
b5da4afe50 | ||
|
|
bca8458787 | ||
|
|
c974cc82e4 | ||
|
|
37d1583665 | ||
|
|
5cdf191d57 | ||
|
|
b7e8630c76 | ||
|
|
37df9e8b9c | ||
|
|
f639e1729f | ||
|
|
019ec6d0a5 | ||
|
|
46f0bbbca4 | ||
|
|
4d927cb2d9 | ||
|
|
72ffd69b45 | ||
|
|
dae71dc9a5 | ||
|
|
119430dc18 | ||
|
|
e2c631ebcf | ||
|
|
4b341bc463 | ||
|
|
1918745f5f | ||
|
|
f96cfaff29 | ||
|
|
cf062a5c35 | ||
|
|
6ab2aa8358 | ||
|
|
e5f8763d74 | ||
|
|
7214b14a7b | ||
|
|
f74131008a | ||
|
|
aadef46ad8 | ||
|
|
ea0538d030 | ||
|
|
15864e39c0 | ||
|
|
e5788ea5dd | ||
|
|
80b7e7d1a0 | ||
|
|
cd56ff1567 | ||
|
|
6a627ac6b7 | ||
|
|
b1953b7b81 | ||
|
|
2c83fb4bc9 | ||
|
|
a3e55d753a | ||
|
|
8720300aa3 | ||
|
|
1d7018b903 | ||
|
|
f2e1fd09d4 | ||
|
|
e0bb18b783 | ||
|
|
c97a787623 | ||
|
|
6944fd8b93 | ||
|
|
df09ff004c | ||
|
|
88f9d846d6 | ||
|
|
83b748720a | ||
|
|
a92cc30ae8 | ||
|
|
ad7c17af90 | ||
|
|
5be5c146c2 | ||
|
|
08f802d982 | ||
|
|
b32ea4a02e | ||
|
|
327e8d1483 | ||
|
|
d5b12139e6 | ||
|
|
f2386073b9 | ||
|
|
03cf81d3a0 | ||
|
|
190a5aaae0 | ||
|
|
051c715c75 | ||
|
|
695a65ac50 | ||
|
|
0eec71b3b3 | ||
|
|
4dbc2501ff | ||
|
|
2633780796 | ||
|
|
707f3fc86f | ||
|
|
878adc3107 | ||
|
|
59798e0590 | ||
|
|
0dbc76cebe | ||
|
|
f9a159ad15 | ||
|
|
b540916109 | ||
|
|
3809f25c85 | ||
|
|
90a10c9650 | ||
|
|
b76ed0ff8e | ||
|
|
0b2c00208c | ||
|
|
0b98021c39 | ||
|
|
e3dd005322 | ||
|
|
0615adf07d | ||
|
|
da725ffc9e | ||
|
|
75b6187a2b | ||
|
|
4f3aac8982 | ||
|
|
5633d34633 | ||
|
|
62b32a6973 | ||
|
|
ad14529669 | ||
|
|
7c3825a968 | ||
|
|
c48720e33d | ||
|
|
d9a01e884d | ||
|
|
8d333acb7b | ||
|
|
9b789ad11d | ||
|
|
b56256fdb4 | ||
|
|
b50e0add79 | ||
|
|
85a644a841 | ||
|
|
c53501d155 | ||
|
|
b1305a65ab | ||
|
|
1c85136168 | ||
|
|
67e553ce4b | ||
|
|
00f981b1fa | ||
|
|
2970b7e726 | ||
|
|
1cfedf9384 | ||
|
|
fb0b12c66d | ||
|
|
047a452f3f | ||
|
|
1a7ce19c97 | ||
|
|
2f64669614 |
94 changed files with 18996 additions and 524 deletions
|
|
@ -319,6 +319,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: |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -29,19 +33,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:
|
||||
|
|
@ -56,9 +50,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'
|
||||
|
|
|
|||
|
|
@ -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 <jami.kettunen@somainline.org>
|
||||
|
||||
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 <dt-bindings/gpio/gpio.h>
|
||||
|
||||
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>;
|
||||
};
|
||||
};
|
||||
|
|
@ -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 <jami.kettunen@somainline.org>
|
||||
|
||||
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 <dt-bindings/gpio/gpio.h>
|
||||
|
||||
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>;
|
||||
};
|
||||
};
|
||||
|
|
@ -55,6 +55,20 @@ properties:
|
|||
reg:
|
||||
maxItems: 1
|
||||
|
||||
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
|
||||
- clock-names
|
||||
|
|
|
|||
|
|
@ -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 <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
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 <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
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>;
|
||||
};
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
# 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,pmi8998-haptics.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm PMI8998/PM660 Haptics
|
||||
|
||||
maintainers:
|
||||
- Caleb Connolly <caleb@connolly.tech>
|
||||
|
||||
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,pm660-charger
|
||||
- qcom,pmi8996-haptics
|
||||
- qcom,pmi8941-haptics
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: short
|
||||
- const: play
|
||||
|
||||
qcom,wave-play-duration-us:
|
||||
description: |
|
||||
Wave sample duration in microseconds, 1/f where f
|
||||
is the resonant frequency of the actuator.
|
||||
This property is named qcom,wave-play-rate-us in
|
||||
downstream kernels.
|
||||
minimum: 0
|
||||
maximum: 20475
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- qcom,wave-play-rate-us
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
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-play-rate-us = <4255>;
|
||||
};
|
||||
};
|
||||
158
Documentation/devicetree/bindings/interconnect/qcom,msm8998.yaml
Normal file
158
Documentation/devicetree/bindings/interconnect/qcom,msm8998.yaml
Normal file
|
|
@ -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 <angelogioacchino.delregno@somainline.org>
|
||||
- Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
|
||||
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 <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/clock/qcom,mmcc-msm8998.h>
|
||||
|
||||
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>;
|
||||
};
|
||||
|
|
@ -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 <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
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 <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -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 <caleb.connolly@linaro.org>
|
||||
|
||||
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 <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
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>;
|
||||
};
|
||||
};
|
||||
241
Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
Normal file
241
Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
Normal file
|
|
@ -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 <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
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 <dt-bindings/clock/qcom,gcc-msm8998.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
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";
|
||||
};
|
||||
...
|
||||
|
|
@ -17022,6 +17022,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 <angelogioacchino.delregno@somainline.org>
|
||||
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 <ilia.lin@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8998-oneplus-dumpling.dtb
|
|||
dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-lilac.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-maple.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-poplar.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += msm8998-xiaomi-sagit.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += qrb5165-rb5.dtb
|
||||
|
|
|
|||
|
|
@ -25,6 +25,15 @@
|
|||
serial1 = &blsp1_uart3;
|
||||
};
|
||||
|
||||
/* 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.
|
||||
|
|
@ -53,6 +62,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>;
|
||||
|
||||
|
|
@ -105,6 +116,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";
|
||||
|
|
@ -182,6 +226,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";
|
||||
|
|
@ -241,8 +332,62 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&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 = "okay";
|
||||
qcom,noise-reject-scl = <3>;
|
||||
qcom,noise-reject-sda = <3>;
|
||||
|
||||
touchscreen@14 {
|
||||
compatible = "goodix,gt9286";
|
||||
|
|
@ -257,6 +402,120 @@
|
|||
};
|
||||
};
|
||||
|
||||
&cpufreq_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&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";
|
||||
};
|
||||
|
||||
&etf {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
@ -342,7 +601,35 @@
|
|||
};
|
||||
};
|
||||
|
||||
&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>;
|
||||
};
|
||||
|
||||
&pmi8998_fg {
|
||||
status = "okay";
|
||||
|
||||
qcom,max-voltage-uv = <4400000>;
|
||||
qcom,min-voltage-uv = <3700000>;
|
||||
qcom,battery-capacity-ua = <3150000>;
|
||||
};
|
||||
|
||||
&pm8998_gpio {
|
||||
unknown_pin_a: unk-active-state {
|
||||
pins = "gpio5";
|
||||
function = "normal";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
|
||||
};
|
||||
|
||||
vol_up_pin_a: vol-up-active-state {
|
||||
pins = "gpio6";
|
||||
function = "normal";
|
||||
|
|
@ -630,6 +917,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";
|
||||
|
|
@ -658,6 +965,13 @@
|
|||
bias-disable;
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
panel_reset_n: panel-rst-n {
|
||||
pins = "gpio94";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhc2 {
|
||||
|
|
|
|||
|
|
@ -41,3 +41,19 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* Capacitive keypad buttons */
|
||||
&rmi4_i2c {
|
||||
rmi4-f1a@1a {
|
||||
reg = <0x1a>;
|
||||
syna,codes = <KEY_BACK KEY_APPSELECT>;
|
||||
};
|
||||
};
|
||||
|
||||
/* Display */
|
||||
&panel {
|
||||
compatible = "samsung,s6e3fa5";
|
||||
|
||||
/* The panel is mounted upside down on the OnePlus 5 */
|
||||
rotation = <180>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,12 +9,27 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
|
||||
#include "msm8998.dtsi"
|
||||
#include "pm8005.dtsi"
|
||||
#include "pm8998.dtsi"
|
||||
#include "pmi8998.dtsi"
|
||||
|
||||
/*
|
||||
* Delete following upstream (msm8998.dtsi) reserved
|
||||
* memory mappings which are different in this device.
|
||||
*/
|
||||
/delete-node/ &adsp_mem;
|
||||
/delete-node/ &mpss_mem;
|
||||
/delete-node/ &venus_mem;
|
||||
/delete-node/ &mba_mem;
|
||||
/delete-node/ &slpi_mem;
|
||||
/delete-node/ &ipa_fw_mem;
|
||||
/delete-node/ &ipa_gsi_mem;
|
||||
/delete-node/ &gpu_mem;
|
||||
/delete-node/ &wlan_msa_mem;
|
||||
|
||||
/ {
|
||||
/* Required for bootloader to select correct board */
|
||||
qcom,msm-id = <292 0x20001>; /* 8998 v2.1 */
|
||||
|
|
@ -45,10 +60,62 @@
|
|||
<&mmcc MDSS_PCLK0_CLK>,
|
||||
<&mmcc MDSS_ESC0_CLK>;
|
||||
power-domains = <&mmcc MDSS_GDSC>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
// FIXME: https://patchwork.kernel.org/project/linux-arm-msm/patch/20220617122007.2307726-1-dsankouski@gmail.com/
|
||||
/*
|
||||
* OnePlus' ADSP firmware requires 30 MiB in total, so increase the adsp_mem
|
||||
* region by 4 MiB to account for this while relocating the other now
|
||||
* conflicting memory nodes accordingly.
|
||||
*/
|
||||
adsp_mem: memory@8b200000 {
|
||||
reg = <0x0 0x8b200000 0x0 0x1e00000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
mpss_mem: memory@8d000000 {
|
||||
reg = <0x0 0x8d000000 0x0 0x7000000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
venus_mem: memory@94000000 {
|
||||
reg = <0x0 0x94000000 0x0 0x500000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
mba_mem: memory@94500000 {
|
||||
reg = <0x0 0x94500000 0x0 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
slpi_mem: memory@94700000 {
|
||||
reg = <0x0 0x94700000 0x0 0xf00000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
ipa_fw_mem: memory@95600000 {
|
||||
reg = <0x0 0x95600000 0x0 0x10000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
ipa_gsi_mem: memory@95610000 {
|
||||
reg = <0x0 0x95610000 0x0 0x5000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
gpu_mem: memory@95615000 {
|
||||
reg = <0x0 0x95615000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
wlan_msa_mem: memory@95715000 {
|
||||
reg = <0x0 0x95715000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
/* Bootloader display framebuffer region */
|
||||
cont_splash_mem: memory@9d400000 {
|
||||
reg = <0x0 0x9d400000 0x0 0x2400000>;
|
||||
|
|
@ -80,6 +147,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 {
|
||||
|
|
@ -95,7 +171,7 @@
|
|||
gpios = <&pm8998_gpio 5 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_VOLUMEDOWN>;
|
||||
debounce-interval = <15>;
|
||||
wakeup-source;
|
||||
wakeup-source; // TODO: remove?
|
||||
};
|
||||
|
||||
button-vol-up {
|
||||
|
|
@ -103,7 +179,7 @@
|
|||
gpios = <&pm8998_gpio 6 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
debounce-interval = <15>;
|
||||
wakeup-source;
|
||||
wakeup-source; // TODO: remove?
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -132,43 +208,18 @@
|
|||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* OnePlus' ADSP firmware requires 30 MiB in total, so increase the adsp_mem
|
||||
* region by 4 MiB to account for this while relocating the other now
|
||||
* conflicting memory nodes accordingly.
|
||||
*/
|
||||
&adsp_mem {
|
||||
reg = <0x0 0x8b200000 0x0 0x1e00000>;
|
||||
&apc_cprh {
|
||||
status = "okay";
|
||||
};
|
||||
&mpss_mem {
|
||||
reg = <0x0 0x8d000000 0x0 0x7000000>;
|
||||
};
|
||||
&venus_mem {
|
||||
reg = <0x0 0x94000000 0x0 0x500000>;
|
||||
};
|
||||
&mba_mem {
|
||||
reg = <0x0 0x94500000 0x0 0x200000>;
|
||||
};
|
||||
&slpi_mem {
|
||||
reg = <0x0 0x94700000 0x0 0xf00000>;
|
||||
};
|
||||
&ipa_fw_mem {
|
||||
reg = <0x0 0x95600000 0x0 0x10000>;
|
||||
};
|
||||
&ipa_gsi_mem {
|
||||
reg = <0x0 0x95610000 0x0 0x5000>;
|
||||
};
|
||||
&gpu_mem {
|
||||
reg = <0x0 0x95615000 0x0 0x100000>;
|
||||
};
|
||||
&wlan_msa_mem {
|
||||
reg = <0x0 0x95715000 0x0 0x100000>;
|
||||
|
||||
&cpufreq_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_i2c5 {
|
||||
status = "okay";
|
||||
|
||||
touchscreen@20 {
|
||||
rmi4_i2c: touchscreen@20 {
|
||||
compatible = "syna,rmi4-i2c";
|
||||
reg = <0x20>;
|
||||
#address-cells = <1>;
|
||||
|
|
@ -201,6 +252,12 @@
|
|||
};
|
||||
};
|
||||
|
||||
&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";
|
||||
|
||||
|
|
@ -254,10 +311,50 @@
|
|||
};
|
||||
};
|
||||
|
||||
&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";
|
||||
};
|
||||
|
||||
&ipa {
|
||||
status = "okay";
|
||||
|
||||
memory-region = <&ipa_fws_region>; // ipa_fw_mem? ipa_gsi_mem?
|
||||
firmware-name = "qcom/msm8998/oneplus/ipa_fws.mbn";
|
||||
};
|
||||
|
||||
&pm8005_regulators {
|
||||
/* VDD_GFX supply */
|
||||
pm8005_s1: s1 {
|
||||
|
|
@ -279,6 +376,23 @@
|
|||
};
|
||||
};
|
||||
|
||||
&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";
|
||||
|
||||
|
|
@ -489,9 +603,139 @@
|
|||
};
|
||||
};
|
||||
|
||||
&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";
|
||||
};
|
||||
|
||||
&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;
|
||||
/delete-node/ opp-414000000;
|
||||
/delete-node/ opp-342000000;
|
||||
};
|
||||
};
|
||||
|
||||
&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";
|
||||
|
|
@ -568,7 +812,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>;
|
||||
|
|
|
|||
|
|
@ -24,3 +24,8 @@
|
|||
&rmi4_f12 {
|
||||
touchscreen-y-mm = <137>;
|
||||
};
|
||||
|
||||
/* Display */
|
||||
&panel {
|
||||
compatible = "samsung,s6e3fc1";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@
|
|||
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>;
|
||||
|
|
|
|||
|
|
@ -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-state {
|
||||
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";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@
|
|||
qcom,soft-start-us = <800>;
|
||||
};
|
||||
|
||||
&wcd9335 {
|
||||
pinctrl-0 = <&cdc_reset_n &wcd_int_n>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&vreg_l18a_2p85 {
|
||||
/* Note: Round-down from 2850000 to be a multiple of PLDO step-size 8000 */
|
||||
regulator-min-microvolt = <2848000>;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
#include <dt-bindings/sound/qcom,q6asm.h>
|
||||
#include "msm8998.dtsi"
|
||||
#include "pm8005.dtsi"
|
||||
#include "pm8998.dtsi"
|
||||
|
|
@ -18,6 +20,10 @@
|
|||
qcom,msm-id = <0x124 0x20000>, <0x124 0x20001>; /* 8998v2, v2.1 */
|
||||
qcom,board-id = <8 0>;
|
||||
|
||||
chosen {
|
||||
bootargs = "clk_ignore_unused root=/dev/mmcblk0p1";
|
||||
};
|
||||
|
||||
clocks {
|
||||
div1_mclk: divclk1 {
|
||||
compatible = "gpio-gate-clock";
|
||||
|
|
@ -80,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";
|
||||
|
|
@ -188,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>;
|
||||
|
|
@ -257,7 +289,10 @@
|
|||
reg = <0x29>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
/* Angelo: not 23? */
|
||||
interrupts = <22 IRQ_TYPE_EDGE_FALLING>;
|
||||
//#io-channel-cells = <1>;
|
||||
//label = "back_camera_tof";
|
||||
|
||||
reset-gpios = <&tlmm 27 GPIO_ACTIVE_LOW>;
|
||||
vdd-supply = <&cam_vio_vreg>;
|
||||
|
|
@ -267,6 +302,62 @@
|
|||
};
|
||||
};
|
||||
|
||||
&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>;
|
||||
|
|
@ -292,10 +383,34 @@
|
|||
regulator-soft-start;
|
||||
};
|
||||
|
||||
&lpass_q6_smmu {
|
||||
qcom,bypass-cbndx = /bits/ 8 <11>;
|
||||
qcom,reset-nodisable-cbs = /bits/ 8 <12>;
|
||||
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&mmcc {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&mmss_smmu {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&mdss {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pm8005_regulators {
|
||||
/* VDD_GFX supply */
|
||||
pm8005_s1: s1 {
|
||||
regulator-min-microvolt = <524000>;
|
||||
/*
|
||||
* 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 */
|
||||
|
|
@ -333,6 +448,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 {
|
||||
|
|
@ -367,6 +489,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";
|
||||
|
||||
|
|
@ -374,6 +527,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";
|
||||
|
|
@ -410,131 +576,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 { };
|
||||
};
|
||||
|
||||
|
|
@ -562,6 +759,371 @@
|
|||
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";
|
||||
|
||||
/*
|
||||
<path name="voicemmode1-call headphones">
|
||||
<ctl name="SLIM_0_RX_Voice Mixer VoiceMMode1" value="1" />
|
||||
<ctl name="VoiceMMode1_Tx Mixer SLIM_0_TX_MMode1" value="1" />
|
||||
</path>
|
||||
|
||||
<path name="sidetone-headphones">
|
||||
<path name="sidetone-iir" />
|
||||
<!-- 45 % of 124 (range 0 - 124) Register: 0x340 -->
|
||||
<ctl name="IIR0 INP0 Volume" value="44" />
|
||||
<ctl name="RX INT1 MIX2 INP" value="SRC0" />
|
||||
<ctl name="RX INT2 MIX2 INP" value="SRC0" />
|
||||
</path>
|
||||
|
||||
<path name="speaker-and-headphones">
|
||||
<path name="speaker" />
|
||||
<ctl name="RX INT1_1 MIX1 INP0" value="RX1" />
|
||||
<ctl name="RX INT2_1 MIX1 INP0" value="RX1" />
|
||||
<ctl name="RX INT1 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX INT2 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX1 Digital Volume" value="55" />
|
||||
<ctl name="RX2 Digital Volume" value="55" />
|
||||
<path name="headphones-hpf" />
|
||||
<ctl name="Set Custom Stereo" value="Mix" />
|
||||
</path>
|
||||
|
||||
<path name="headphones">
|
||||
<ctl name="SLIM RX0 MUX" value="AIF_MIX1_PB" />
|
||||
<ctl name="SLIM RX1 MUX" value="AIF_MIX1_PB" />
|
||||
<ctl name="SLIM_0_RX Channels" value="Two" />
|
||||
<ctl name="RX INT1_1 MIX1 INP0" value="RX0" />
|
||||
<ctl name="RX INT2_1 MIX1 INP0" value="RX1" />
|
||||
<ctl name="RX INT1 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX INT2 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX1 Digital Volume" value="80" />
|
||||
<ctl name="RX2 Digital Volume" value="80" />
|
||||
</path>
|
||||
|
||||
<path name="headphones-hpf">
|
||||
<ctl name="RX INT1_1 HPF cut off" value="CF_NEG_3DB_150HZ" />
|
||||
<ctl name="RX INT2_1 HPF cut off" value="CF_NEG_3DB_150HZ" />
|
||||
</path>
|
||||
|
||||
|
||||
<path name="anc-off-headphone">
|
||||
<ctl name="SLIM RX0 MUX" value="AIF_MIX1_PB" />
|
||||
<ctl name="SLIM RX1 MUX" value="AIF_MIX1_PB" />
|
||||
<ctl name="SLIM_0_RX Channels" value="Two" />
|
||||
<ctl name="RX INT1_1 MIX1 INP0" value="RX0" />
|
||||
<ctl name="RX INT2_1 MIX1 INP0" value="RX1" />
|
||||
<ctl name="RX INT1 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX INT2 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="COMP1 Switch" value="0" />
|
||||
<ctl name="COMP2 Switch" value="0" />
|
||||
<ctl name="HPHL Volume" value="20" />
|
||||
<ctl name="HPHR Volume" value="20" />
|
||||
<ctl name="RX1 Digital Volume" value="77" />
|
||||
<ctl name="RX2 Digital Volume" value="77" />
|
||||
</path>
|
||||
|
||||
<path name="audio-record">
|
||||
<ctl name="MultiMedia1 Mixer SLIM_0_TX" value="1" />
|
||||
</path>
|
||||
|
||||
<path name="deep-buffer-playback">
|
||||
<ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia1" value="1" />
|
||||
</path>
|
||||
*/
|
||||
|
||||
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 {
|
||||
gpio-reserved-ranges = <0 4>, <81 4>;
|
||||
|
||||
|
|
@ -642,6 +1204,67 @@
|
|||
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>;
|
||||
};
|
||||
|
||||
hall_sensor0_default: acc-cover-open {
|
||||
|
|
|
|||
947
arch/arm64/boot/dts/qcom/msm8998-xiaomi-sagit.dts
Normal file
947
arch/arm64/boot/dts/qcom/msm8998-xiaomi-sagit.dts
Normal file
|
|
@ -0,0 +1,947 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
/*
|
||||
* Xiaomi Mi 6 (sagit) device tree source based on msm8998-mtp.dtsi
|
||||
*
|
||||
* Copyright (c) 2022, Degdag Mohamed <degdagmohamed@gmail.com>
|
||||
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "msm8998.dtsi"
|
||||
#include "pm8005.dtsi"
|
||||
#include "pm8998.dtsi"
|
||||
#include "pmi8998.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
|
||||
|
||||
/*
|
||||
* Delete following upstream (msm8998.dtsi) reserved
|
||||
* memory mappings which are different in this device.
|
||||
*/
|
||||
/delete-node/ &adsp_mem;
|
||||
/delete-node/ &mpss_mem;
|
||||
/delete-node/ &venus_mem;
|
||||
/delete-node/ &mba_mem;
|
||||
/delete-node/ &slpi_mem;
|
||||
/delete-node/ &ipa_fw_mem;
|
||||
/delete-node/ &ipa_gsi_mem;
|
||||
/delete-node/ &gpu_mem;
|
||||
/delete-node/ &wlan_msa_mem;
|
||||
|
||||
/ {
|
||||
model = "Xiaomi Mi 6";
|
||||
compatible = "xiaomi,sagit", "qcom,msm8998";
|
||||
chassis-type = "handset";
|
||||
/* Required for bootloader to select correct board */
|
||||
qcom,board-id = <30 0>;
|
||||
qcom,msm-id = <292 0x20001>; /* 8998 v2.1 */
|
||||
|
||||
chosen {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
/* Use display framebuffer setup by the UEFI XBL bootloader for simplefb */
|
||||
framebuffer0: framebuffer@9d400000 {
|
||||
compatible = "simple-framebuffer";
|
||||
reg = <0x0 0x9d400000 0x0 0x2400000>;
|
||||
width = <1080>;
|
||||
height = <1920>;
|
||||
stride = <(1080 * 4)>;
|
||||
format = "a8r8g8b8";
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
/*
|
||||
* Xiaomi's ADSP firmware requires 30 MiB in total, so increase the adsp_mem
|
||||
* region by 4 MiB to account for this while relocating the other now
|
||||
* conflicting memory nodes accordingly.
|
||||
*/
|
||||
adsp_mem: memory@8b200000 {
|
||||
reg = <0x0 0x8b200000 0x0 0x1e00000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
mpss_mem: memory@8d000000 {
|
||||
reg = <0x0 0x8d000000 0x0 0x7000000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
venus_mem: memory@94000000 {
|
||||
reg = <0x0 0x94000000 0x0 0x500000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
mba_mem: memory@94500000 {
|
||||
reg = <0x0 0x94500000 0x0 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
slpi_mem: memory@94700000 {
|
||||
reg = <0x0 0x94700000 0x0 0xf00000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
ipa_fw_mem: memory@95600000 {
|
||||
reg = <0x0 0x95600000 0x0 0x10000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
ipa_gsi_mem: memory@95610000 {
|
||||
reg = <0x0 0x95610000 0x0 0x5000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
gpu_mem: memory@95615000 {
|
||||
reg = <0x0 0x95615000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
wlan_msa_mem: memory@95715000 {
|
||||
reg = <0x0 0x95715000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
/* Bootloader display framebuffer region */
|
||||
cont_splash_mem: memory@9d400000 {
|
||||
reg = <0x0 0x9d400000 0x0 0x2400000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
/* For getting crash logs using Android downstream kernels */
|
||||
ramoops@ac000000 {
|
||||
compatible = "ramoops";
|
||||
reg = <0x0 0xac000000 0x0 0x200000>;
|
||||
console-size = <0x80000>;
|
||||
pmsg-size = <0x40000>;
|
||||
record-size = <0x8000>;
|
||||
ftrace-size = <0x20000>;
|
||||
};
|
||||
|
||||
/*
|
||||
* The following memory regions on downstream are "dynamically allocated"
|
||||
* but given the same addresses every time. Hard code them as these addresses
|
||||
* are where the Xiaomi signed firmware expects them to be.
|
||||
*/
|
||||
ipa_fws_region: memory@f7800000 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x0 0xf7800000 0x0 0x5000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
zap_shader_region: memory@f7900000 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x0 0xf7900000 0x0 0x2000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
label = "Volume buttons";
|
||||
autorepeat;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&vol_up_key_default>;
|
||||
|
||||
vol-up {
|
||||
label = "Volume up";
|
||||
gpios = <&pm8998_gpio 6 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
debounce-interval = <15>;
|
||||
wakeup-source;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-hall-sensor {
|
||||
compatible = "gpio-keys";
|
||||
label = "Hall effect sensor";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hall_sensor_default>;
|
||||
|
||||
hall-sensor {
|
||||
label = "Hall Effect Sensor";
|
||||
gpios = <&tlmm 124 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <EV_SW>;
|
||||
linux,code = <SW_LID>;
|
||||
linux,can-disable;
|
||||
wakeup-source;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
div1_mclk: divclk1 {
|
||||
compatible = "gpio-gate-clock";
|
||||
pinctrl-0 = <&audio_mclk_pin>;
|
||||
pinctrl-names = "default";
|
||||
clocks = <&rpmcc RPM_SMD_DIV_CLK1>;
|
||||
#clock-cells = <0>;
|
||||
enable-gpios = <&pm8998_gpio 13 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
vph_pwr: vph-pwr-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vph_pwr";
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
disp_vddts_vreg: disp_vddts_vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "disp_vddts_vreg";
|
||||
gpio = <&tlmm 50 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
regulator-boot-on;
|
||||
};
|
||||
};
|
||||
|
||||
&apc_cprh {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpufreq_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_i2c5 {
|
||||
pinctrl-names = "default", "sleep";
|
||||
status = "okay";
|
||||
|
||||
synaptics-rmi4-i2c@20 {
|
||||
compatible = "syna,rmi4-i2c";
|
||||
reg = <0x20>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <125 IRQ_TYPE_EDGE_FALLING>;
|
||||
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&ts_active>;
|
||||
pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
|
||||
|
||||
vdd-supply = <&disp_vddts_vreg>;
|
||||
vio-supply = <&vreg_l6a_1p8>;
|
||||
|
||||
syna,reset-delay-ms = <20>;
|
||||
syna,startup-delay-ms = <20>;
|
||||
|
||||
rmi4-f01@1 {
|
||||
reg = <0x01>;
|
||||
syna,nosleep-mode = <1>;
|
||||
};
|
||||
|
||||
rmi4-f12@12 {
|
||||
reg = <0x12>;
|
||||
touchscreen-x-mm = <64>;
|
||||
touchscreen-y-mm = <114>;
|
||||
syna,sensor-type = <1>;
|
||||
syna,rezero-wait-ms = <20>;
|
||||
};
|
||||
|
||||
rmi4-f1a@1a {
|
||||
reg = <0x1a>;
|
||||
syna,codes = <KEY_BACK KEY_APPSELECT>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_i2c5_sleep {
|
||||
/delete-property/ bias-pull-up;
|
||||
/* Configure a no-pull on TP I2C sleep to match downstream. */
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
&blsp1_uart3 {
|
||||
status = "okay";
|
||||
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn3990-bt";
|
||||
|
||||
vddio-supply = <&vreg_s4a_1p8>;
|
||||
vddxo-supply = <&vreg_l7a_1p8>;
|
||||
vddrf-supply = <&vreg_l17a_1p3>;
|
||||
vddch0-supply = <&vreg_l25a_3p3>;
|
||||
max-speed = <3200000>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_uart3_on {
|
||||
rx {
|
||||
/delete-property/ bias-disable;
|
||||
/*
|
||||
* Configure a pull-up on 46 (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;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp2_uart1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ipa {
|
||||
status = "okay";
|
||||
|
||||
memory-region = <&ipa_fws_region>; // ipa_fw_mem? ipa_gsi_mem?
|
||||
firmware-name = "qcom/msm8998/xiaomi/ipa_fws.mbn";
|
||||
};
|
||||
|
||||
&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_up_key_default: vol_up_key_default {
|
||||
pins = "gpio6";
|
||||
function = "normal";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
|
||||
};
|
||||
|
||||
audio_mclk_pin: audio-mclk-pin-active {
|
||||
pins = "gpio13";
|
||||
function = "func2";
|
||||
power-source = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&pmi8998_fg {
|
||||
status = "okay";
|
||||
|
||||
qcom,max-voltage-uv = <4400000>;
|
||||
qcom,min-voltage-uv = <3700000>;
|
||||
qcom,battery-capacity-ua = <3350000>;
|
||||
};
|
||||
|
||||
&pmi8998_lpg {
|
||||
status = "okay";
|
||||
|
||||
notification-led {
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
reg = <0x5>;
|
||||
};
|
||||
};
|
||||
|
||||
&pmi8998_haptics {
|
||||
status = "okay";
|
||||
|
||||
qcom,wave-play-rate-us = <5000>;
|
||||
};
|
||||
|
||||
&qusb2phy {
|
||||
status = "okay";
|
||||
|
||||
vdda-pll-supply = <&vreg_l12a_1p8>;
|
||||
vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
|
||||
};
|
||||
|
||||
&rpm_requests {
|
||||
pm8998-regulators {
|
||||
compatible = "qcom,rpm-pm8998-regulators";
|
||||
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
vdd_s2-supply = <&vph_pwr>;
|
||||
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_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_l20_l24-supply = <&vreg_bob>;
|
||||
vdd_l26-supply = <&vreg_s3a_1p35>;
|
||||
vdd_lvs1_lvs2-supply = <&vreg_s4a_1p8>;
|
||||
|
||||
vreg_s3a_1p35: s3 {
|
||||
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>;
|
||||
};
|
||||
|
||||
vreg_l2a_1p2: l2 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
};
|
||||
|
||||
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>;
|
||||
};
|
||||
|
||||
vreg_l14a_1p8: l14 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
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_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-system-load = <800000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
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>;
|
||||
};
|
||||
|
||||
vreg_l26a_1p2: l26 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l28_3p0: l28 {
|
||||
regulator-min-microvolt = <3008000>;
|
||||
regulator-max-microvolt = <3008000>;
|
||||
};
|
||||
|
||||
vreg_lvs1a_1p8: lvs1 { };
|
||||
vreg_lvs2a_1p8: lvs2 { };
|
||||
};
|
||||
|
||||
pmi8998-regulators {
|
||||
compatible = "qcom,rpm-pmi8998-regulators";
|
||||
|
||||
vdd_bob-supply = <&vph_pwr>;
|
||||
|
||||
vreg_bob: bob {
|
||||
regulator-min-microvolt = <3312000>;
|
||||
regulator-max-microvolt = <3600000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&remoteproc_adsp {
|
||||
status = "okay";
|
||||
|
||||
firmware-name = "qcom/msm8998/xiaomi/adsp.mbn";
|
||||
};
|
||||
|
||||
&remoteproc_mss {
|
||||
status = "okay";
|
||||
|
||||
firmware-name = "qcom/msm8998/xiaomi/mba.mbn", "qcom/msm8998/xiaomi/modem.mbn";
|
||||
};
|
||||
|
||||
&remoteproc_slpi {
|
||||
status = "okay";
|
||||
|
||||
firmware-name = "qcom/msm8998/xiaomi/slpi_v2.mbn";
|
||||
};
|
||||
|
||||
&mmcc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mmss_smmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mdss {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mdss_mdp {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
||||
vdd-supply = <&vreg_l1a_0p875>;
|
||||
vdda-supply = <&vreg_l2a_1p2>;
|
||||
|
||||
panel: panel@0 {
|
||||
compatible = "jdi,fhd-r63452";
|
||||
reg = <0x0>;
|
||||
|
||||
backlight = <&pmi8998_wled>;
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
|
||||
disp-te-gpios = <&tlmm 10 GPIO_ACTIVE_LOW>;
|
||||
|
||||
ibb-supply = <&ibb>;
|
||||
lab-supply = <&lab>;
|
||||
vddio-supply = <&vreg_l14a_1p8>;
|
||||
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&mdss_dsi_active &mdss_te_active>;
|
||||
pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
|
||||
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>;
|
||||
};
|
||||
|
||||
&ibb {
|
||||
regulator-min-microvolt = <4600000>;
|
||||
regulator-max-microvolt = <6000000>;
|
||||
regulator-min-microamp = <800000>;
|
||||
regulator-max-microamp = <800000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-over-current-protection;
|
||||
regulator-pull-down;
|
||||
regulator-ramp-delay = <1>;
|
||||
regulator-settling-time-up-us = <600>;
|
||||
regulator-settling-time-down-us = <1000>;
|
||||
regulator-soft-start;
|
||||
qcom,discharge-resistor-kohms = <300>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
&lab {
|
||||
regulator-min-microvolt = <4600000>;
|
||||
regulator-max-microvolt = <6000000>;
|
||||
qcom,soft-start-us = <800>;
|
||||
regulator-min-microamp = <200000>;
|
||||
regulator-max-microamp = <200000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
regulator-over-current-protection;
|
||||
regulator-pull-down;
|
||||
regulator-ramp-delay = <1>;
|
||||
regulator-settling-time-up-us = <50000>;
|
||||
regulator-settling-time-down-us = <3000>;
|
||||
regulator-soft-start;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
&lpass_q6_smmu {
|
||||
qcom,bypass-cbndx = /bits/ 8 <11>;
|
||||
qcom,reset-nodisable-cbs = /bits/ 8 <12>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* 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/xiaomi/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>;
|
||||
|
||||
hall_sensor_default: hall-sensor-default {
|
||||
pins = "gpio124";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
input-enable;
|
||||
};
|
||||
mdss_dsi_active: mdss_dsi_active {
|
||||
pins = "gpio94";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
mdss_dsi_suspend: mdss_dsi_suspend {
|
||||
pins = "gpio94";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
mdss_te_active: mdss_te_active {
|
||||
pins = "gpio10";
|
||||
function = "mdp_vsync_a";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
mdss_te_suspend: mdss_te_suspend {
|
||||
pins = "gpio10";
|
||||
function = "mdp_vsync_a";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
ts_active: ts_active {
|
||||
pins = "gpio89", "gpio125";
|
||||
function = "gpio";
|
||||
drive-strength = <16>;
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
};
|
||||
|
||||
ts_reset_suspend: ts_reset_suspend {
|
||||
pins = "gpio89";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
ts_int_suspend: ts_int_suspend {
|
||||
pins = "gpio125";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
nfc_int_active: nfc_int_active {
|
||||
pins = "gpio92";
|
||||
function = "gpio";
|
||||
drive-strength = <6>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
nfc_int_suspend: nfc_int_suspend {
|
||||
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;
|
||||
};
|
||||
|
||||
nfc_enable_suspend: nfc_enable_suspend {
|
||||
pins = "gpio12", "gpio116";
|
||||
function = "gpio";
|
||||
drive-strength = <6>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
msm_mclk0_default: msm-mclk0-active {
|
||||
pins = "gpio13";
|
||||
function = "cam_mclk";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
msm_mclk1_default: msm-mclk1-active {
|
||||
pins = "gpio14";
|
||||
function = "cam_mclk";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
cci1_default: cci1-default {
|
||||
pins = "gpio18", "gpio19";
|
||||
function = "cci_i2c";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
cci1_default: cci1-default {
|
||||
pins = "gpio19", "gpio20";
|
||||
function = "cci_i2c";
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
&pm8998_pon {
|
||||
resin {
|
||||
compatible = "qcom,pm8941-resin";
|
||||
interrupts = <GIC_SPI 0x8 1 IRQ_TYPE_EDGE_BOTH>;
|
||||
debounce = <15625>;
|
||||
bias-pull-up;
|
||||
linux,code = <KEY_VOLUMEDOWN>;
|
||||
};
|
||||
};
|
||||
|
||||
&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 = <4>;
|
||||
qcom,enabled-strings = <0 1 2 3>;
|
||||
};
|
||||
|
||||
&ufshc {
|
||||
status = "okay";
|
||||
|
||||
vcc-supply = <&vreg_l20a_2p95>;
|
||||
vccq-supply = <&vreg_l26a_1p2>;
|
||||
vccq2-supply = <&vreg_s4a_1p8>;
|
||||
vcc-max-microamp = <750000>;
|
||||
vccq-max-microamp = <560000>;
|
||||
vccq2-max-microamp = <750000>;
|
||||
};
|
||||
|
||||
&ufsphy {
|
||||
status = "okay";
|
||||
|
||||
vdda-phy-supply = <&vreg_l1a_0p875>;
|
||||
vdda-pll-supply = <&vreg_l2a_1p2>;
|
||||
vddp-ref-clk-supply = <&vreg_l26a_1p2>;
|
||||
vdda-phy-max-microamp = <51400>;
|
||||
vdda-pll-max-microamp = <14600>;
|
||||
vddp-ref-clk-max-microamp = <100>;
|
||||
vddp-ref-clk-always-on;
|
||||
};
|
||||
|
||||
&usb3 {
|
||||
status = "okay";
|
||||
|
||||
/* Disable USB3 clock requirement as the device only supports USB2 */
|
||||
qcom,select-utmi-as-pipe-clk;
|
||||
};
|
||||
|
||||
&usb3_dwc3 {
|
||||
/* Drop the unused USB 3 PHY */
|
||||
phys = <&qusb2phy>;
|
||||
phy-names = "usb2-phy";
|
||||
|
||||
/* Fastest mode for USB 2 */
|
||||
maximum-speed = "high-speed";
|
||||
|
||||
/* Force to peripheral until we can switch modes */
|
||||
dr_mode = "peripheral";
|
||||
};
|
||||
|
||||
&wifi {
|
||||
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>;
|
||||
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
|
||||
};
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -78,6 +78,16 @@
|
|||
#size-cells = <0>;
|
||||
#io-channel-cells = <1>;
|
||||
|
||||
adc-chan@0 {
|
||||
reg = <ADC5_REF_GND>;
|
||||
label = "ref_gnd";
|
||||
};
|
||||
|
||||
adc-chan@1 {
|
||||
reg = <ADC5_REF_GND>;
|
||||
label = "vref_1p25";
|
||||
};
|
||||
|
||||
adc-chan@6 {
|
||||
reg = <ADC5_DIE_TEMP>;
|
||||
label = "die_temp";
|
||||
|
|
|
|||
|
|
@ -9,6 +9,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 +35,24 @@
|
|||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pmi8998_fg: fuel-gauge@4000 {
|
||||
compatible = "qcom,pmi8998-fg";
|
||||
reg = <0x4000>;
|
||||
|
||||
interrupts = <0x2 0x40 0x3 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "soc-delta";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pmi8998_rradc: rradc@4500 {
|
||||
compatible = "qcom,pmi8998-rradc";
|
||||
reg = <0x4500>;
|
||||
#io-channel-cells = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
pmi8998_lsid1: pmic@3 {
|
||||
|
|
@ -62,5 +97,16 @@
|
|||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
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";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1185,19 +1185,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 {
|
||||
|
|
|
|||
563
arch/arm64/configs/msm8998_defconfig
Normal file
563
arch/arm64/configs/msm8998_defconfig
Normal file
|
|
@ -0,0 +1,563 @@
|
|||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_PSI=y
|
||||
# CONFIG_CPU_ISOLATION is not set
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_CFS_BANDWIDTH=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_CGROUP_PIDS=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
# CONFIG_TIME_NS is not set
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_RD_BZIP2 is not set
|
||||
# CONFIG_RD_LZMA is not set
|
||||
# CONFIG_RD_LZO is not set
|
||||
# CONFIG_RD_ZSTD is not set
|
||||
# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
|
||||
CONFIG_PERF_EVENTS=y
|
||||
CONFIG_ARCH_QCOM=y
|
||||
# CONFIG_ARM64_ERRATUM_826319 is not set
|
||||
# CONFIG_ARM64_ERRATUM_827319 is not set
|
||||
# CONFIG_ARM64_ERRATUM_824069 is not set
|
||||
# CONFIG_ARM64_ERRATUM_819472 is not set
|
||||
# CONFIG_ARM64_ERRATUM_832075 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1742098 is not set
|
||||
# CONFIG_ARM64_ERRATUM_843419 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1024718 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1418040 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1165522 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1319367 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1530923 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2441007 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1286807 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1463225 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1542419 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1508412 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2051678 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2077057 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2658417 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2054223 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2067961 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2441009 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_22375 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_23154 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_27456 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_30115 is not set
|
||||
# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set
|
||||
# CONFIG_FUJITSU_ERRATUM_010001 is not set
|
||||
# CONFIG_HISILICON_ERRATUM_161600802 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
|
||||
# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set
|
||||
# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set
|
||||
# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_SCHED_CLUSTER=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_HZ_1000=y
|
||||
# CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set
|
||||
# CONFIG_ARM64_TAGGED_ADDR_ABI is not set
|
||||
CONFIG_COMPAT=y
|
||||
# CONFIG_ARM64_RAS_EXTN is not set
|
||||
# CONFIG_ARM64_CNP is not set
|
||||
# CONFIG_ARM64_PTR_AUTH is not set
|
||||
# CONFIG_ARM64_AMU_EXTN is not set
|
||||
# CONFIG_ARM64_TLB_RANGE is not set
|
||||
# CONFIG_ARM64_BTI is not set
|
||||
# CONFIG_ARM64_E0PD is not set
|
||||
# CONFIG_ARM64_EPAN is not set
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
# CONFIG_EFI is not set
|
||||
# CONFIG_SUSPEND is not set
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_PM_ADVANCED_DEBUG=y
|
||||
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
|
||||
CONFIG_ENERGY_MODEL=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_CPU_IDLE_GOV_MENU=y
|
||||
CONFIG_CPU_IDLE_GOV_TEO=y
|
||||
CONFIG_ARM_PSCI_CPUIDLE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
|
||||
CONFIG_ARM_QCOM_CPUFREQ_HW=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
# CONFIG_STACKPROTECTOR is not set
|
||||
CONFIG_SHADOW_CALL_STACK=y
|
||||
# CONFIG_VMAP_STACK is not set
|
||||
# CONFIG_GCC_PLUGINS is not set
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_COMPRESS_XZ=y
|
||||
# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_IOSCHED_BFQ=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_ZSMALLOC_STAT=y
|
||||
# CONFIG_SLAB_MERGE_DEFAULT is not set
|
||||
# CONFIG_SLUB_CPU_PARTIAL is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_KSM=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_LRU_GEN=y
|
||||
CONFIG_LRU_GEN_ENABLED=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_PACKET_DIAG=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_IPV6=m
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_BRIDGE_NETFILTER=m
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_TABLES=m
|
||||
CONFIG_NF_TABLES_INET=y
|
||||
CONFIG_NFT_CT=m
|
||||
CONFIG_NFT_LOG=m
|
||||
CONFIG_NFT_LIMIT=m
|
||||
CONFIG_NFT_MASQ=m
|
||||
CONFIG_NFT_NAT=m
|
||||
CONFIG_NFT_REJECT=m
|
||||
CONFIG_NETFILTER_XT_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_IPVS=m
|
||||
CONFIG_IP_VS=m
|
||||
CONFIG_IP_VS_PROTO_TCP=y
|
||||
CONFIG_IP_VS_PROTO_UDP=y
|
||||
CONFIG_IP_VS_RR=m
|
||||
CONFIG_IP_VS_NFCT=y
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_NAT=m
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_NAT=m
|
||||
CONFIG_IP6_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_BRIDGE_VLAN_FILTERING=y
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_CLS_CGROUP=m
|
||||
CONFIG_NETLINK_DIAG=y
|
||||
CONFIG_QRTR=m
|
||||
CONFIG_QRTR_SMD=m
|
||||
CONFIG_QRTR_TUN=m
|
||||
CONFIG_CGROUP_NET_PRIO=y
|
||||
CONFIG_BT=m
|
||||
CONFIG_BT_RFCOMM=m
|
||||
CONFIG_BT_RFCOMM_TTY=y
|
||||
CONFIG_BT_BNEP=m
|
||||
CONFIG_BT_BNEP_MC_FILTER=y
|
||||
CONFIG_BT_BNEP_PROTO_FILTER=y
|
||||
CONFIG_BT_HIDP=m
|
||||
CONFIG_BT_HS=y
|
||||
CONFIG_BT_HCIUART=m
|
||||
CONFIG_BT_HCIUART_QCA=y
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_MESH=y
|
||||
CONFIG_RFKILL=m
|
||||
CONFIG_NFC=m
|
||||
CONFIG_NFC_NCI=m
|
||||
CONFIG_NFC_NXP_NCI=m
|
||||
CONFIG_NFC_NXP_NCI_I2C=m
|
||||
CONFIG_UEVENT_HELPER=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_QCOM_SSC_BLOCK_BUS=y
|
||||
# CONFIG_ARM_SMCCC_SOC_ID is not set
|
||||
CONFIG_ZRAM=m
|
||||
CONFIG_ZRAM_MEMORY_TRACKING=y
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_QCOM_FASTRPC=m
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_SCSI_SCAN_ASYNC=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_THIN_PROVISIONING=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_MACVLAN=m
|
||||
CONFIG_IPVLAN=m
|
||||
CONFIG_VXLAN=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VETH=m
|
||||
# CONFIG_NET_VENDOR_ALACRITECH is not set
|
||||
# CONFIG_NET_VENDOR_AMAZON is not set
|
||||
# CONFIG_NET_VENDOR_AMD is not set
|
||||
# CONFIG_NET_VENDOR_AQUANTIA is not set
|
||||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_VENDOR_ASIX is not set
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_NET_VENDOR_CADENCE is not set
|
||||
# CONFIG_NET_VENDOR_CAVIUM is not set
|
||||
# CONFIG_NET_VENDOR_CORTINA is not set
|
||||
# CONFIG_NET_VENDOR_DAVICOM is not set
|
||||
# CONFIG_NET_VENDOR_ENGLEDER is not set
|
||||
# CONFIG_NET_VENDOR_EZCHIP is not set
|
||||
# CONFIG_NET_VENDOR_FUNGIBLE is not set
|
||||
# CONFIG_NET_VENDOR_GOOGLE is not set
|
||||
# CONFIG_NET_VENDOR_HISILICON is not set
|
||||
# CONFIG_NET_VENDOR_HUAWEI is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_WANGXUN is not set
|
||||
# CONFIG_NET_VENDOR_LITEX is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_MELLANOX is not set
|
||||
# CONFIG_NET_VENDOR_MICREL is not set
|
||||
# CONFIG_NET_VENDOR_MICROCHIP is not set
|
||||
# CONFIG_NET_VENDOR_MICROSEMI is not set
|
||||
# CONFIG_NET_VENDOR_MICROSOFT is not set
|
||||
# CONFIG_NET_VENDOR_NI is not set
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
# CONFIG_NET_VENDOR_NETRONOME is not set
|
||||
# CONFIG_NET_VENDOR_PENSANDO is not set
|
||||
CONFIG_RMNET=m
|
||||
# CONFIG_NET_VENDOR_RENESAS is not set
|
||||
# CONFIG_NET_VENDOR_ROCKER is not set
|
||||
# CONFIG_NET_VENDOR_SAMSUNG is not set
|
||||
# CONFIG_NET_VENDOR_SEEQ is not set
|
||||
# CONFIG_NET_VENDOR_SOLARFLARE is not set
|
||||
# CONFIG_NET_VENDOR_SMSC is not set
|
||||
# CONFIG_NET_VENDOR_SOCIONEXT is not set
|
||||
# CONFIG_NET_VENDOR_STMICRO is not set
|
||||
# CONFIG_NET_VENDOR_SYNOPSYS is not set
|
||||
# CONFIG_NET_VENDOR_VERTEXCOM is not set
|
||||
# CONFIG_NET_VENDOR_VIA is not set
|
||||
# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
# CONFIG_NET_VENDOR_XILINX is not set
|
||||
CONFIG_QCOM_IPA=m
|
||||
# CONFIG_WLAN_VENDOR_ADMTEK is not set
|
||||
CONFIG_ATH10K=m
|
||||
CONFIG_ATH10K_SNOC=m
|
||||
# CONFIG_WLAN_VENDOR_ATMEL is not set
|
||||
# CONFIG_WLAN_VENDOR_BROADCOM is not set
|
||||
# CONFIG_WLAN_VENDOR_CISCO is not set
|
||||
# CONFIG_WLAN_VENDOR_INTEL is not set
|
||||
# CONFIG_WLAN_VENDOR_INTERSIL is not set
|
||||
# CONFIG_WLAN_VENDOR_MARVELL is not set
|
||||
# CONFIG_WLAN_VENDOR_MEDIATEK is not set
|
||||
# CONFIG_WLAN_VENDOR_MICROCHIP is not set
|
||||
# CONFIG_WLAN_VENDOR_PURELIFI is not set
|
||||
# CONFIG_WLAN_VENDOR_RALINK is not set
|
||||
# CONFIG_WLAN_VENDOR_REALTEK is not set
|
||||
# CONFIG_WLAN_VENDOR_RSI is not set
|
||||
# CONFIG_WLAN_VENDOR_SILABS is not set
|
||||
# CONFIG_WLAN_VENDOR_ST is not set
|
||||
# CONFIG_WLAN_VENDOR_TI is not set
|
||||
# CONFIG_WLAN_VENDOR_ZYDAS is not set
|
||||
# CONFIG_WLAN_VENDOR_QUANTENNA is not set
|
||||
CONFIG_INPUT_FF_MEMLESS=y
|
||||
CONFIG_INPUT_EVDEV=m
|
||||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
CONFIG_KEYBOARD_GPIO=y
|
||||
CONFIG_KEYBOARD_GPIO_FASTMATRIX=y
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_GOODIX=m
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_PM8941_PWRKEY=y
|
||||
CONFIG_INPUT_QCOM_SPMI_HAPTICS=m
|
||||
CONFIG_INPUT_UINPUT=m
|
||||
CONFIG_RMI4_CORE=m
|
||||
CONFIG_RMI4_I2C=m
|
||||
CONFIG_RMI4_F12=y
|
||||
CONFIG_RMI4_F1A=y
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_LDISC_AUTOLOAD is not set
|
||||
CONFIG_SERIAL_MSM=m
|
||||
CONFIG_SERIAL_DEV_BUS=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_DEVMEM is not set
|
||||
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
|
||||
# CONFIG_I2C_COMPAT is not set
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_QCOM_CCI=m
|
||||
CONFIG_I2C_QUP=m
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_PINCTRL_AW9523=y
|
||||
CONFIG_PINCTRL_MSM=y
|
||||
CONFIG_PINCTRL_MSM8998=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_GPIO_WCD934X=m
|
||||
CONFIG_POWER_RESET_MSM=y
|
||||
CONFIG_POWER_RESET_QCOM_PON=y
|
||||
CONFIG_BATTERY_BQ27XXX=m
|
||||
CONFIG_CHARGER_QCOM_SMB2=m
|
||||
CONFIG_BATTERY_QCOM_FG=m
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_DEVFREQ_THERMAL=y
|
||||
CONFIG_QCOM_TSENS=y
|
||||
CONFIG_QCOM_SPMI_TEMP_ALARM=y
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_MFD_WCD934X=m
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_QCOM_SMD_RPM=y
|
||||
CONFIG_REGULATOR_QCOM_SPMI=y
|
||||
CONFIG_REGULATOR_QCOM_LABIBB=y
|
||||
CONFIG_MEDIA_SUPPORT=m
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_PLATFORM_SUPPORT=y
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_V4L_MEM2MEM_DRIVERS=y
|
||||
CONFIG_VIDEO_QCOM_CAMSS=m
|
||||
CONFIG_VIDEO_IMX355=m
|
||||
CONFIG_DRM=y
|
||||
# CONFIG_DRM_USE_DYNAMIC_DEBUG is not set
|
||||
CONFIG_DRM_MSM=m
|
||||
# CONFIG_DRM_MSM_MDP4 is not set
|
||||
# CONFIG_DRM_MSM_MDP5 is not set
|
||||
# CONFIG_DRM_MSM_DSI_28NM_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_20NM_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_28NM_8960_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_14NM_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_7NM_PHY is not set
|
||||
CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0=y
|
||||
CONFIG_DRM_PANEL_JDI_R63452=y
|
||||
CONFIG_DRM_PANEL_NOVATEK_NT35950=y
|
||||
CONFIG_DRM_PANEL_SAMSUNG_S6E3FA5=y
|
||||
CONFIG_DRM_PANEL_SAMSUNG_S6E3FC1=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_BACKLIGHT_QCOM_WLED=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
|
||||
CONFIG_SOUND=m
|
||||
CONFIG_SND=m
|
||||
# CONFIG_SND_SUPPORT_OLD_API is not set
|
||||
# CONFIG_SND_VERBOSE_PROCFS is not set
|
||||
# CONFIG_SND_DRIVERS is not set
|
||||
CONFIG_SND_SOC=m
|
||||
CONFIG_SND_SOC_QCOM=m
|
||||
CONFIG_SND_SOC_MSM8998=m
|
||||
CONFIG_SND_SOC_WCD9335=m
|
||||
CONFIG_SND_SOC_WCD934X=m
|
||||
CONFIG_SND_SOC_LPASS_WSA_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_VA_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_RX_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_TX_MACRO=m
|
||||
CONFIG_HID_BATTERY_STRENGTH=y
|
||||
CONFIG_HIDRAW=y
|
||||
# CONFIG_HID_A4TECH is not set
|
||||
# CONFIG_HID_APPLE is not set
|
||||
# CONFIG_HID_BELKIN is not set
|
||||
# CONFIG_HID_CHERRY is not set
|
||||
# CONFIG_HID_CHICONY is not set
|
||||
# CONFIG_HID_CYPRESS is not set
|
||||
# CONFIG_HID_EZKEY is not set
|
||||
# CONFIG_HID_ITE is not set
|
||||
# CONFIG_HID_KENSINGTON is not set
|
||||
# CONFIG_HID_LOGITECH is not set
|
||||
# CONFIG_HID_REDRAGON is not set
|
||||
# CONFIG_HID_MICROSOFT is not set
|
||||
# CONFIG_HID_MONTEREY is not set
|
||||
CONFIG_HID_NINTENDO=m
|
||||
CONFIG_NINTENDO_FF=y
|
||||
CONFIG_HID_SONY=m
|
||||
CONFIG_SONY_FF=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_DWC3=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_VBUS_DRAW=500
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
CONFIG_USB_CONFIGFS_RNDIS=y
|
||||
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
CONFIG_USB_CONFIGFS_F_HID=y
|
||||
CONFIG_USB_CONFIGFS_F_UVC=y
|
||||
CONFIG_USB_FUNCTIONFS=m
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_MSM=y
|
||||
CONFIG_SCSI_UFSHCD=y
|
||||
CONFIG_SCSI_UFS_HPB=y
|
||||
CONFIG_SCSI_UFSHCD_PLATFORM=y
|
||||
CONFIG_SCSI_UFS_QCOM=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=m
|
||||
CONFIG_LEDS_CLASS_FLASH=m
|
||||
CONFIG_LEDS_CLASS_MULTICOLOR=m
|
||||
CONFIG_LEDS_GPIO=m
|
||||
CONFIG_LEDS_QCOM_LPG=m
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_ONESHOT=y
|
||||
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
|
||||
CONFIG_LEDS_TRIGGER_ACTIVITY=y
|
||||
CONFIG_LEDS_TRIGGER_GPIO=y
|
||||
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
|
||||
CONFIG_LEDS_TRIGGER_CAMERA=y
|
||||
CONFIG_LEDS_TRIGGER_PANIC=y
|
||||
CONFIG_LEDS_TRIGGER_NETDEV=y
|
||||
CONFIG_LEDS_TRIGGER_PATTERN=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_HCTOSYS is not set
|
||||
CONFIG_RTC_DRV_PM8XXX=m
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_QCOM_BAM_DMA=y
|
||||
# CONFIG_VIRTIO_MENU is not set
|
||||
# CONFIG_VHOST_MENU is not set
|
||||
CONFIG_STAGING=y
|
||||
# CONFIG_SURFACE_PLATFORMS is not set
|
||||
CONFIG_COMMON_CLK_QCOM=y
|
||||
CONFIG_QCOM_CLK_SMD_RPM=y
|
||||
CONFIG_MSM_GPUCC_8998=y
|
||||
CONFIG_MSM_MMCC_8998=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_QCOM=m
|
||||
# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
|
||||
# CONFIG_FSL_ERRATUM_A008585 is not set
|
||||
# CONFIG_HISILICON_ERRATUM_161010101 is not set
|
||||
# CONFIG_ARM64_ERRATUM_858921 is not set
|
||||
CONFIG_MAILBOX=y
|
||||
CONFIG_QCOM_APCS_IPC=y
|
||||
CONFIG_ARM_SMMU=y
|
||||
CONFIG_QCOM_IOMMU=y
|
||||
CONFIG_REMOTEPROC=y
|
||||
CONFIG_REMOTEPROC_CDEV=y
|
||||
CONFIG_QCOM_Q6V5_ADSP=m
|
||||
CONFIG_QCOM_Q6V5_MSS=m
|
||||
CONFIG_QCOM_Q6V5_PAS=m
|
||||
CONFIG_QCOM_SYSMON=m
|
||||
CONFIG_RPMSG_CHAR=m
|
||||
CONFIG_RPMSG_NS=m
|
||||
CONFIG_RPMSG_QCOM_GLINK_RPM=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
|
||||
CONFIG_RPMSG_QCOM_SMD=m
|
||||
CONFIG_SOUNDWIRE=m
|
||||
CONFIG_SOUNDWIRE_QCOM=m
|
||||
CONFIG_QCOM_CPR3=y
|
||||
CONFIG_QCOM_RMTFS_MEM=m
|
||||
CONFIG_QCOM_RPMPD=y
|
||||
CONFIG_QCOM_SMEM=y
|
||||
CONFIG_QCOM_SMD_RPM=y
|
||||
CONFIG_QCOM_SMP2P=m
|
||||
CONFIG_QCOM_SPM=y
|
||||
CONFIG_QCOM_STATS=m
|
||||
CONFIG_QCOM_APR=m
|
||||
CONFIG_QCOM_ICC_BWMON=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_EXTCON_USB_GPIO=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_QCOM_SPMI_VADC=y
|
||||
CONFIG_QCOM_SPMI_ADC5=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PHY_QCOM_QMP=y
|
||||
CONFIG_PHY_QCOM_QUSB2=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_ANDROID_BINDERFS=y
|
||||
CONFIG_NVMEM_QCOM_QFPROM=y
|
||||
CONFIG_SLIM_QCOM_CTRL=m
|
||||
CONFIG_SLIM_QCOM_NGD_CTRL=m
|
||||
CONFIG_INTERCONNECT=y
|
||||
CONFIG_INTERCONNECT_QCOM=y
|
||||
CONFIG_INTERCONNECT_QCOM_MSM8998=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_F2FS_FS=y
|
||||
CONFIG_F2FS_FS_SECURITY=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
# CONFIG_PRINT_QUOTA_WARNING is not set
|
||||
CONFIG_QFMT_V2=y
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_OVERLAY_FS=m
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON=y
|
||||
CONFIG_SQUASHFS=m
|
||||
CONFIG_SQUASHFS_FILE_DIRECT=y
|
||||
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_UNICODE=y
|
||||
CONFIG_KEY_DH_OPERATIONS=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_DISABLE=y
|
||||
CONFIG_DEFAULT_SECURITY_DAC=y
|
||||
CONFIG_CRYPTO_DES=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
CONFIG_CRYPTO_HCTR2=m
|
||||
CONFIG_CRYPTO_XTS=m
|
||||
CONFIG_CRYPTO_MD5=m
|
||||
CONFIG_CRYPTO_LZ4=m
|
||||
CONFIG_CRYPTO_USER_API_HASH=m
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=m
|
||||
# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set
|
||||
CONFIG_CRYPTO_NHPOLY1305_NEON=m
|
||||
CONFIG_CRYPTO_CHACHA20_NEON=m
|
||||
CONFIG_CRYPTO_GHASH_ARM64_CE=m
|
||||
CONFIG_CRYPTO_POLY1305_NEON=m
|
||||
CONFIG_CRYPTO_SHA1_ARM64_CE=m
|
||||
CONFIG_CRYPTO_SHA2_ARM64_CE=m
|
||||
CONFIG_CRYPTO_SHA512_ARM64_CE=m
|
||||
CONFIG_CRYPTO_POLYVAL_ARM64_CE=m
|
||||
CONFIG_CRYPTO_AES_ARM64=m
|
||||
CONFIG_CRYPTO_AES_ARM64_CE_BLK=m
|
||||
CONFIG_CRYPTO_AES_ARM64_BS=m
|
||||
CONFIG_CRYPTO_SM4_ARM64_CE_BLK=m
|
||||
CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=m
|
||||
CONFIG_CRYPTO_AES_ARM64_CE_CCM=m
|
||||
CONFIG_PKCS8_PRIVATE_KEY_PARSER=m
|
||||
CONFIG_FORCE_NR_CPUS=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
# CONFIG_RCU_TRACE is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
# CONFIG_RUNTIME_TESTING_MENU is not set
|
||||
552
arch/arm64/configs/oneplus5_defconfig
Normal file
552
arch/arm64/configs/oneplus5_defconfig
Normal file
|
|
@ -0,0 +1,552 @@
|
|||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_PSI=y
|
||||
# CONFIG_CPU_ISOLATION is not set
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_CFS_BANDWIDTH=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_CGROUP_PIDS=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
# CONFIG_TIME_NS is not set
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_RD_BZIP2 is not set
|
||||
# CONFIG_RD_LZMA is not set
|
||||
# CONFIG_RD_LZO is not set
|
||||
# CONFIG_RD_ZSTD is not set
|
||||
# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
|
||||
CONFIG_PERF_EVENTS=y
|
||||
CONFIG_ARCH_QCOM=y
|
||||
# CONFIG_ARM64_ERRATUM_826319 is not set
|
||||
# CONFIG_ARM64_ERRATUM_827319 is not set
|
||||
# CONFIG_ARM64_ERRATUM_824069 is not set
|
||||
# CONFIG_ARM64_ERRATUM_819472 is not set
|
||||
# CONFIG_ARM64_ERRATUM_832075 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1742098 is not set
|
||||
# CONFIG_ARM64_ERRATUM_843419 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1024718 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1418040 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1165522 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1319367 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1530923 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2441007 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1286807 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1463225 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1542419 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1508412 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2051678 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2077057 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2658417 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2054223 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2067961 is not set
|
||||
# CONFIG_ARM64_ERRATUM_2441009 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_22375 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_23154 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_27456 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_30115 is not set
|
||||
# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set
|
||||
# CONFIG_FUJITSU_ERRATUM_010001 is not set
|
||||
# CONFIG_HISILICON_ERRATUM_161600802 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
|
||||
# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set
|
||||
# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set
|
||||
# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_SCHED_CLUSTER=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_HZ_1000=y
|
||||
# CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set
|
||||
# CONFIG_ARM64_TAGGED_ADDR_ABI is not set
|
||||
CONFIG_COMPAT=y
|
||||
# CONFIG_ARM64_RAS_EXTN is not set
|
||||
# CONFIG_ARM64_CNP is not set
|
||||
# CONFIG_ARM64_PTR_AUTH is not set
|
||||
# CONFIG_ARM64_AMU_EXTN is not set
|
||||
# CONFIG_ARM64_TLB_RANGE is not set
|
||||
# CONFIG_ARM64_BTI is not set
|
||||
# CONFIG_ARM64_E0PD is not set
|
||||
# CONFIG_ARM64_EPAN is not set
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
# CONFIG_EFI is not set
|
||||
# CONFIG_SUSPEND is not set
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_PM_ADVANCED_DEBUG=y
|
||||
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
|
||||
CONFIG_ENERGY_MODEL=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_CPU_IDLE_GOV_MENU=y
|
||||
CONFIG_CPU_IDLE_GOV_TEO=y
|
||||
CONFIG_ARM_PSCI_CPUIDLE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
|
||||
CONFIG_ARM_QCOM_CPUFREQ_HW=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
# CONFIG_STACKPROTECTOR is not set
|
||||
CONFIG_SHADOW_CALL_STACK=y
|
||||
# CONFIG_VMAP_STACK is not set
|
||||
# CONFIG_GCC_PLUGINS is not set
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_COMPRESS_XZ=y
|
||||
# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_IOSCHED_BFQ=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_ZSMALLOC_STAT=y
|
||||
# CONFIG_SLAB_MERGE_DEFAULT is not set
|
||||
# CONFIG_SLUB_CPU_PARTIAL is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_KSM=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_LRU_GEN=y
|
||||
CONFIG_LRU_GEN_ENABLED=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_PACKET_DIAG=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_IPV6=m
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_BRIDGE_NETFILTER=m
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_TABLES=m
|
||||
CONFIG_NF_TABLES_INET=y
|
||||
CONFIG_NFT_CT=m
|
||||
CONFIG_NFT_LOG=m
|
||||
CONFIG_NFT_LIMIT=m
|
||||
CONFIG_NFT_MASQ=m
|
||||
CONFIG_NFT_NAT=m
|
||||
CONFIG_NFT_REJECT=m
|
||||
CONFIG_NETFILTER_XT_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_IPVS=m
|
||||
CONFIG_IP_VS=m
|
||||
CONFIG_IP_VS_PROTO_TCP=y
|
||||
CONFIG_IP_VS_PROTO_UDP=y
|
||||
CONFIG_IP_VS_RR=m
|
||||
CONFIG_IP_VS_NFCT=y
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_NAT=m
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_NAT=m
|
||||
CONFIG_IP6_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_BRIDGE_VLAN_FILTERING=y
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_CLS_CGROUP=m
|
||||
CONFIG_NETLINK_DIAG=y
|
||||
CONFIG_QRTR=m
|
||||
CONFIG_QRTR_SMD=m
|
||||
CONFIG_QRTR_TUN=m
|
||||
CONFIG_CGROUP_NET_PRIO=y
|
||||
CONFIG_BT=m
|
||||
CONFIG_BT_RFCOMM=m
|
||||
CONFIG_BT_RFCOMM_TTY=y
|
||||
CONFIG_BT_BNEP=m
|
||||
CONFIG_BT_BNEP_MC_FILTER=y
|
||||
CONFIG_BT_BNEP_PROTO_FILTER=y
|
||||
CONFIG_BT_HIDP=m
|
||||
CONFIG_BT_HS=y
|
||||
CONFIG_BT_HCIUART=m
|
||||
CONFIG_BT_HCIUART_QCA=y
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_MESH=y
|
||||
CONFIG_RFKILL=m
|
||||
CONFIG_NFC=m
|
||||
CONFIG_NFC_NCI=m
|
||||
CONFIG_NFC_NXP_NCI=m
|
||||
CONFIG_NFC_NXP_NCI_I2C=m
|
||||
CONFIG_UEVENT_HELPER=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_QCOM_SSC_BLOCK_BUS=y
|
||||
# CONFIG_ARM_SMCCC_SOC_ID is not set
|
||||
CONFIG_ZRAM=m
|
||||
CONFIG_ZRAM_MEMORY_TRACKING=y
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_QCOM_FASTRPC=m
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_SCSI_SCAN_ASYNC=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_THIN_PROVISIONING=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_MACVLAN=m
|
||||
CONFIG_IPVLAN=m
|
||||
CONFIG_VXLAN=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VETH=m
|
||||
# CONFIG_NET_VENDOR_ALACRITECH is not set
|
||||
# CONFIG_NET_VENDOR_AMAZON is not set
|
||||
# CONFIG_NET_VENDOR_AMD is not set
|
||||
# CONFIG_NET_VENDOR_AQUANTIA is not set
|
||||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_VENDOR_ASIX is not set
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_NET_VENDOR_CADENCE is not set
|
||||
# CONFIG_NET_VENDOR_CAVIUM is not set
|
||||
# CONFIG_NET_VENDOR_CORTINA is not set
|
||||
# CONFIG_NET_VENDOR_DAVICOM is not set
|
||||
# CONFIG_NET_VENDOR_ENGLEDER is not set
|
||||
# CONFIG_NET_VENDOR_EZCHIP is not set
|
||||
# CONFIG_NET_VENDOR_FUNGIBLE is not set
|
||||
# CONFIG_NET_VENDOR_GOOGLE is not set
|
||||
# CONFIG_NET_VENDOR_HISILICON is not set
|
||||
# CONFIG_NET_VENDOR_HUAWEI is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_WANGXUN is not set
|
||||
# CONFIG_NET_VENDOR_LITEX is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_MELLANOX is not set
|
||||
# CONFIG_NET_VENDOR_MICREL is not set
|
||||
# CONFIG_NET_VENDOR_MICROCHIP is not set
|
||||
# CONFIG_NET_VENDOR_MICROSEMI is not set
|
||||
# CONFIG_NET_VENDOR_MICROSOFT is not set
|
||||
# CONFIG_NET_VENDOR_NI is not set
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
# CONFIG_NET_VENDOR_NETRONOME is not set
|
||||
# CONFIG_NET_VENDOR_PENSANDO is not set
|
||||
CONFIG_RMNET=m
|
||||
# CONFIG_NET_VENDOR_RENESAS is not set
|
||||
# CONFIG_NET_VENDOR_ROCKER is not set
|
||||
# CONFIG_NET_VENDOR_SAMSUNG is not set
|
||||
# CONFIG_NET_VENDOR_SEEQ is not set
|
||||
# CONFIG_NET_VENDOR_SOLARFLARE is not set
|
||||
# CONFIG_NET_VENDOR_SMSC is not set
|
||||
# CONFIG_NET_VENDOR_SOCIONEXT is not set
|
||||
# CONFIG_NET_VENDOR_STMICRO is not set
|
||||
# CONFIG_NET_VENDOR_SYNOPSYS is not set
|
||||
# CONFIG_NET_VENDOR_VERTEXCOM is not set
|
||||
# CONFIG_NET_VENDOR_VIA is not set
|
||||
# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
# CONFIG_NET_VENDOR_XILINX is not set
|
||||
CONFIG_QCOM_IPA=m
|
||||
# CONFIG_WLAN_VENDOR_ADMTEK is not set
|
||||
CONFIG_ATH10K=m
|
||||
CONFIG_ATH10K_SNOC=m
|
||||
# CONFIG_WLAN_VENDOR_ATMEL is not set
|
||||
# CONFIG_WLAN_VENDOR_BROADCOM is not set
|
||||
# CONFIG_WLAN_VENDOR_CISCO is not set
|
||||
# CONFIG_WLAN_VENDOR_INTEL is not set
|
||||
# CONFIG_WLAN_VENDOR_INTERSIL is not set
|
||||
# CONFIG_WLAN_VENDOR_MARVELL is not set
|
||||
# CONFIG_WLAN_VENDOR_MEDIATEK is not set
|
||||
# CONFIG_WLAN_VENDOR_MICROCHIP is not set
|
||||
# CONFIG_WLAN_VENDOR_PURELIFI is not set
|
||||
# CONFIG_WLAN_VENDOR_RALINK is not set
|
||||
# CONFIG_WLAN_VENDOR_REALTEK is not set
|
||||
# CONFIG_WLAN_VENDOR_RSI is not set
|
||||
# CONFIG_WLAN_VENDOR_SILABS is not set
|
||||
# CONFIG_WLAN_VENDOR_ST is not set
|
||||
# CONFIG_WLAN_VENDOR_TI is not set
|
||||
# CONFIG_WLAN_VENDOR_ZYDAS is not set
|
||||
# CONFIG_WLAN_VENDOR_QUANTENNA is not set
|
||||
CONFIG_INPUT_FF_MEMLESS=y
|
||||
CONFIG_INPUT_EVDEV=m
|
||||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
CONFIG_KEYBOARD_GPIO=y
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_PM8941_PWRKEY=y
|
||||
CONFIG_INPUT_QCOM_SPMI_HAPTICS=m
|
||||
CONFIG_INPUT_UINPUT=m
|
||||
CONFIG_RMI4_CORE=m
|
||||
CONFIG_RMI4_I2C=m
|
||||
CONFIG_RMI4_F12=y
|
||||
CONFIG_RMI4_F1A=y
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_LDISC_AUTOLOAD is not set
|
||||
CONFIG_SERIAL_MSM=m
|
||||
CONFIG_SERIAL_DEV_BUS=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_DEVMEM is not set
|
||||
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
|
||||
# CONFIG_I2C_COMPAT is not set
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_QCOM_CCI=m
|
||||
CONFIG_I2C_QUP=m
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_PINCTRL_MSM=y
|
||||
CONFIG_PINCTRL_MSM8998=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_GPIO_WCD934X=m
|
||||
CONFIG_POWER_RESET_MSM=y
|
||||
CONFIG_POWER_RESET_QCOM_PON=y
|
||||
CONFIG_BATTERY_BQ27XXX=m
|
||||
CONFIG_CHARGER_QCOM_SMB2=m
|
||||
CONFIG_BATTERY_QCOM_FG=m
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_DEVFREQ_THERMAL=y
|
||||
CONFIG_QCOM_TSENS=y
|
||||
CONFIG_QCOM_SPMI_TEMP_ALARM=y
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_MFD_WCD934X=m
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_QCOM_SMD_RPM=y
|
||||
CONFIG_REGULATOR_QCOM_SPMI=y
|
||||
CONFIG_REGULATOR_QCOM_LABIBB=y
|
||||
CONFIG_MEDIA_SUPPORT=m
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_PLATFORM_SUPPORT=y
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_V4L_MEM2MEM_DRIVERS=y
|
||||
CONFIG_VIDEO_QCOM_CAMSS=m
|
||||
CONFIG_VIDEO_IMX355=m
|
||||
CONFIG_DRM=y
|
||||
# CONFIG_DRM_USE_DYNAMIC_DEBUG is not set
|
||||
CONFIG_DRM_MSM=m
|
||||
# CONFIG_DRM_MSM_MDP4 is not set
|
||||
# CONFIG_DRM_MSM_MDP5 is not set
|
||||
# CONFIG_DRM_MSM_DP is not set
|
||||
# CONFIG_DRM_MSM_DSI_28NM_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_20NM_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_28NM_8960_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_14NM_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_7NM_PHY is not set
|
||||
# CONFIG_DRM_MSM_HDMI is not set
|
||||
CONFIG_DRM_PANEL_SAMSUNG_S6E3FA5=y
|
||||
CONFIG_DRM_PANEL_SAMSUNG_S6E3FC1=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
|
||||
CONFIG_SOUND=m
|
||||
CONFIG_SND=m
|
||||
# CONFIG_SND_SUPPORT_OLD_API is not set
|
||||
# CONFIG_SND_VERBOSE_PROCFS is not set
|
||||
# CONFIG_SND_DRIVERS is not set
|
||||
CONFIG_SND_SOC=m
|
||||
CONFIG_SND_SOC_QCOM=m
|
||||
CONFIG_SND_SOC_MSM8998=m
|
||||
CONFIG_SND_SOC_WCD9335=m
|
||||
CONFIG_SND_SOC_WCD934X=m
|
||||
CONFIG_SND_SOC_LPASS_WSA_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_VA_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_RX_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_TX_MACRO=m
|
||||
CONFIG_HID_BATTERY_STRENGTH=y
|
||||
CONFIG_HIDRAW=y
|
||||
# CONFIG_HID_A4TECH is not set
|
||||
# CONFIG_HID_APPLE is not set
|
||||
# CONFIG_HID_BELKIN is not set
|
||||
# CONFIG_HID_CHERRY is not set
|
||||
# CONFIG_HID_CHICONY is not set
|
||||
# CONFIG_HID_CYPRESS is not set
|
||||
# CONFIG_HID_EZKEY is not set
|
||||
# CONFIG_HID_ITE is not set
|
||||
# CONFIG_HID_KENSINGTON is not set
|
||||
# CONFIG_HID_LOGITECH is not set
|
||||
# CONFIG_HID_REDRAGON is not set
|
||||
# CONFIG_HID_MICROSOFT is not set
|
||||
# CONFIG_HID_MONTEREY is not set
|
||||
CONFIG_HID_NINTENDO=m
|
||||
CONFIG_NINTENDO_FF=y
|
||||
CONFIG_HID_SONY=m
|
||||
CONFIG_SONY_FF=y
|
||||
CONFIG_USB=m
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_DWC3=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_VBUS_DRAW=500
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
CONFIG_USB_CONFIGFS_RNDIS=y
|
||||
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
CONFIG_USB_CONFIGFS_F_HID=y
|
||||
CONFIG_USB_CONFIGFS_F_UVC=y
|
||||
CONFIG_USB_FUNCTIONFS=m
|
||||
CONFIG_USB_ROLE_SWITCH=y
|
||||
CONFIG_SCSI_UFSHCD=y
|
||||
CONFIG_SCSI_UFS_HPB=y
|
||||
CONFIG_SCSI_UFSHCD_PLATFORM=y
|
||||
CONFIG_SCSI_UFS_QCOM=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=m
|
||||
CONFIG_LEDS_CLASS_FLASH=m
|
||||
CONFIG_LEDS_CLASS_MULTICOLOR=m
|
||||
CONFIG_LEDS_GPIO=m
|
||||
CONFIG_LEDS_QCOM_LPG=m
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_ONESHOT=y
|
||||
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
|
||||
CONFIG_LEDS_TRIGGER_ACTIVITY=y
|
||||
CONFIG_LEDS_TRIGGER_GPIO=y
|
||||
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
|
||||
CONFIG_LEDS_TRIGGER_CAMERA=y
|
||||
CONFIG_LEDS_TRIGGER_PANIC=y
|
||||
CONFIG_LEDS_TRIGGER_NETDEV=y
|
||||
CONFIG_LEDS_TRIGGER_PATTERN=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_HCTOSYS is not set
|
||||
CONFIG_RTC_DRV_PM8XXX=m
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_QCOM_BAM_DMA=y
|
||||
# CONFIG_VIRTIO_MENU is not set
|
||||
# CONFIG_VHOST_MENU is not set
|
||||
CONFIG_STAGING=y
|
||||
# CONFIG_SURFACE_PLATFORMS is not set
|
||||
CONFIG_COMMON_CLK_QCOM=y
|
||||
CONFIG_QCOM_CLK_SMD_RPM=y
|
||||
CONFIG_MSM_GPUCC_8998=y
|
||||
CONFIG_MSM_MMCC_8998=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_QCOM=m
|
||||
# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
|
||||
# CONFIG_FSL_ERRATUM_A008585 is not set
|
||||
# CONFIG_HISILICON_ERRATUM_161010101 is not set
|
||||
# CONFIG_ARM64_ERRATUM_858921 is not set
|
||||
CONFIG_MAILBOX=y
|
||||
CONFIG_QCOM_APCS_IPC=y
|
||||
CONFIG_ARM_SMMU=y
|
||||
CONFIG_QCOM_IOMMU=y
|
||||
CONFIG_REMOTEPROC=y
|
||||
CONFIG_REMOTEPROC_CDEV=y
|
||||
CONFIG_QCOM_Q6V5_ADSP=m
|
||||
CONFIG_QCOM_Q6V5_MSS=m
|
||||
CONFIG_QCOM_Q6V5_PAS=m
|
||||
CONFIG_QCOM_SYSMON=m
|
||||
CONFIG_RPMSG_CHAR=m
|
||||
CONFIG_RPMSG_NS=m
|
||||
CONFIG_RPMSG_QCOM_GLINK_RPM=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
|
||||
CONFIG_RPMSG_QCOM_SMD=m
|
||||
CONFIG_SOUNDWIRE=m
|
||||
CONFIG_SOUNDWIRE_QCOM=m
|
||||
CONFIG_QCOM_CPR3=y
|
||||
CONFIG_QCOM_RMTFS_MEM=m
|
||||
CONFIG_QCOM_RPMPD=y
|
||||
CONFIG_QCOM_SMEM=y
|
||||
CONFIG_QCOM_SMD_RPM=y
|
||||
CONFIG_QCOM_SMP2P=m
|
||||
CONFIG_QCOM_SPM=y
|
||||
CONFIG_QCOM_STATS=m
|
||||
CONFIG_QCOM_APR=m
|
||||
CONFIG_QCOM_ICC_BWMON=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_QCOM_SPMI_VADC=y
|
||||
CONFIG_QCOM_SPMI_ADC5=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PHY_QCOM_QMP=y
|
||||
CONFIG_PHY_QCOM_QUSB2=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_ANDROID_BINDERFS=y
|
||||
CONFIG_NVMEM_QCOM_QFPROM=y
|
||||
CONFIG_SLIM_QCOM_CTRL=m
|
||||
CONFIG_SLIM_QCOM_NGD_CTRL=m
|
||||
CONFIG_INTERCONNECT=y
|
||||
CONFIG_INTERCONNECT_QCOM=y
|
||||
CONFIG_INTERCONNECT_QCOM_MSM8998=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_F2FS_FS=y
|
||||
CONFIG_F2FS_FS_SECURITY=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
# CONFIG_PRINT_QUOTA_WARNING is not set
|
||||
CONFIG_QFMT_V2=y
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_OVERLAY_FS=m
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON=y
|
||||
CONFIG_SQUASHFS=m
|
||||
CONFIG_SQUASHFS_FILE_DIRECT=y
|
||||
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_UNICODE=y
|
||||
CONFIG_KEY_DH_OPERATIONS=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_DISABLE=y
|
||||
CONFIG_DEFAULT_SECURITY_DAC=y
|
||||
CONFIG_CRYPTO_DES=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
CONFIG_CRYPTO_HCTR2=m
|
||||
CONFIG_CRYPTO_XTS=m
|
||||
CONFIG_CRYPTO_MD5=m
|
||||
CONFIG_CRYPTO_LZ4=m
|
||||
CONFIG_CRYPTO_USER_API_HASH=m
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=m
|
||||
# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set
|
||||
CONFIG_CRYPTO_NHPOLY1305_NEON=m
|
||||
CONFIG_CRYPTO_CHACHA20_NEON=m
|
||||
CONFIG_CRYPTO_GHASH_ARM64_CE=m
|
||||
CONFIG_CRYPTO_POLY1305_NEON=m
|
||||
CONFIG_CRYPTO_SHA1_ARM64_CE=m
|
||||
CONFIG_CRYPTO_SHA2_ARM64_CE=m
|
||||
CONFIG_CRYPTO_SHA512_ARM64_CE=m
|
||||
CONFIG_CRYPTO_POLYVAL_ARM64_CE=m
|
||||
CONFIG_CRYPTO_AES_ARM64=m
|
||||
CONFIG_CRYPTO_AES_ARM64_CE_BLK=m
|
||||
CONFIG_CRYPTO_AES_ARM64_BS=m
|
||||
CONFIG_CRYPTO_SM4_ARM64_CE_BLK=m
|
||||
CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=m
|
||||
CONFIG_CRYPTO_AES_ARM64_CE_CCM=m
|
||||
CONFIG_PKCS8_PRIVATE_KEY_PARSER=m
|
||||
CONFIG_FORCE_NR_CPUS=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
# CONFIG_RCU_TRACE is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
# CONFIG_RUNTIME_TESTING_MENU is not set
|
||||
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
@ -2885,6 +2887,43 @@ static struct clk_branch ssc_cnoc_ahbs_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,
|
||||
|
|
@ -2915,6 +2954,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,
|
||||
|
|
@ -3092,12 +3151,17 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
|
|||
[AGGRE2_SNOC_NORTH_AXI] = &aggre2_snoc_north_axi_clk.clkr,
|
||||
[SSC_XO] = &ssc_xo_clk.clkr,
|
||||
[SSC_CNOC_AHBS_CLK] = &ssc_cnoc_ahbs_clk.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[] = {
|
||||
|
|
@ -3247,6 +3311,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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,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" },
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -133,7 +133,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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -1684,6 +1731,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,
|
||||
|
|
@ -1706,6 +1767,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,
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -371,6 +371,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/a619_gmu.bin");
|
||||
MODULE_FIRMWARE("qcom/a630_sqe.fw");
|
||||
MODULE_FIRMWARE("qcom/a630_gmu.bin");
|
||||
|
|
|
|||
|
|
@ -98,7 +98,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 true;
|
||||
}
|
||||
|
||||
static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -443,12 +443,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);
|
||||
|
|
|
|||
|
|
@ -484,6 +484,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
|
||||
|
|
|
|||
|
|
@ -47,6 +47,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
|
||||
|
|
|
|||
361
drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c
Normal file
361
drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2021 Jami Kettunen <jami.kettunen@protonmail.com>
|
||||
* Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
struct s6e3fa5 {
|
||||
struct drm_panel panel;
|
||||
enum drm_panel_orientation orientation;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator *supply;
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline struct s6e3fa5 *to_s6e3fa5_panel(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct s6e3fa5, panel);
|
||||
}
|
||||
|
||||
#define dsi_dcs_write_seq(dsi, seq...) do { \
|
||||
static const u8 d[] = { seq }; \
|
||||
int ret; \
|
||||
ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
static void s6e3fa5_reset(struct s6e3fa5 *ctx)
|
||||
{
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
}
|
||||
|
||||
static int s6e3fa5_on(struct s6e3fa5 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(20);
|
||||
|
||||
ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set tear on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a);
|
||||
dsi_dcs_write_seq(dsi, 0xb0, 0x04);
|
||||
dsi_dcs_write_seq(dsi, 0xb4, 0x06, 0x0c, 0x12);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0xa5, 0xa5);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a);
|
||||
dsi_dcs_write_seq(dsi, 0xc3, 0x01);
|
||||
dsi_dcs_write_seq(dsi, 0xb0, 0x18);
|
||||
dsi_dcs_write_seq(dsi, 0xc3, 0x00);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0xa5, 0xa5);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_off(struct s6e3fa5 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_off(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display off: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(40);
|
||||
|
||||
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(160);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fa5 *ctx = to_s6e3fa5_panel(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_enable(ctx->supply);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
s6e3fa5_reset(ctx);
|
||||
|
||||
ret = s6e3fa5_on(ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
regulator_disable(ctx->supply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->prepared = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fa5 *ctx = to_s6e3fa5_panel(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = s6e3fa5_off(ctx);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
regulator_disable(ctx->supply);
|
||||
|
||||
ctx->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode s6e3fa5_mode = {
|
||||
.clock = (1080 + 120 + 19 + 70) * (1920 + 18 + 2 + 4) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 120,
|
||||
.hsync_end = 1080 + 120 + 19,
|
||||
.htotal = 1080 + 120 + 19 + 70,
|
||||
.vdisplay = 1920,
|
||||
.vsync_start = 1920 + 18,
|
||||
.vsync_end = 1920 + 18 + 2,
|
||||
.vtotal = 1920 + 18 + 2 + 4,
|
||||
.width_mm = 68,
|
||||
.height_mm = 122,
|
||||
};
|
||||
|
||||
static int s6e3fa5_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
struct s6e3fa5 *ctx;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &s6e3fa5_mode);
|
||||
if (!mode)
|
||||
return -ENOMEM;
|
||||
ctx = to_s6e3fa5_panel(panel);
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
/*
|
||||
* TODO: Remove once all drm drivers call
|
||||
* drm_connector_set_orientation_from_panel()
|
||||
*/
|
||||
drm_connector_set_panel_orientation(connector, ctx->orientation);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static enum drm_panel_orientation s6e3fa5_get_orientation(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fa5 *ctx = to_s6e3fa5_panel(panel);
|
||||
|
||||
return ctx->orientation;
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs s6e3fa5_panel_funcs = {
|
||||
.prepare = s6e3fa5_prepare,
|
||||
.unprepare = s6e3fa5_unprepare,
|
||||
.get_modes = s6e3fa5_get_modes,
|
||||
.get_orientation = s6e3fa5_get_orientation,
|
||||
};
|
||||
|
||||
static int s6e3fa5_bl_update_status(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness = backlight_get_brightness(bl);
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_bl_get_brightness(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return brightness & 0xff;
|
||||
}
|
||||
|
||||
static const struct backlight_ops s6e3fa5_bl_ops = {
|
||||
.update_status = s6e3fa5_bl_update_status,
|
||||
.get_brightness = s6e3fa5_bl_get_brightness,
|
||||
};
|
||||
|
||||
static struct backlight_device *
|
||||
s6e3fa5_create_backlight(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
const struct backlight_properties props = {
|
||||
.type = BACKLIGHT_RAW,
|
||||
.brightness = 255,
|
||||
.max_brightness = 255,
|
||||
};
|
||||
|
||||
return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
|
||||
&s6e3fa5_bl_ops, &props);
|
||||
}
|
||||
|
||||
static int s6e3fa5_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct s6e3fa5 *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->supply = devm_regulator_get(dev, "vddio");
|
||||
if (IS_ERR(ctx->supply))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->supply),
|
||||
"Failed to get vddio regulator\n");
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ctx->reset_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
|
||||
"Failed to get reset-gpios\n");
|
||||
|
||||
ctx->dsi = dsi;
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
|
||||
dsi->lanes = 4;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_HSE |
|
||||
MIPI_DSI_MODE_NO_EOT_PACKET |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
ret = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to parse rotation property: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &s6e3fa5_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->panel.backlight = s6e3fa5_create_backlight(dsi);
|
||||
if (IS_ERR(ctx->panel.backlight))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
|
||||
"Failed to create backlight\n");
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
|
||||
drm_panel_remove(&ctx->panel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void s6e3fa5_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct s6e3fa5 *ctx = mipi_dsi_get_drvdata(dsi);
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_detach(dsi);
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
|
||||
|
||||
drm_panel_remove(&ctx->panel);
|
||||
}
|
||||
|
||||
static const struct of_device_id s6e3fa5_of_match[] = {
|
||||
{ .compatible = "samsung,s6e3fa5" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, s6e3fa5_of_match);
|
||||
|
||||
static struct mipi_dsi_driver s6e3fa5_driver = {
|
||||
.probe = s6e3fa5_probe,
|
||||
.remove = s6e3fa5_remove,
|
||||
.driver = {
|
||||
.name = "panel-samsung-s6e3fa5",
|
||||
.of_match_table = s6e3fa5_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(s6e3fa5_driver);
|
||||
|
||||
MODULE_AUTHOR("Jami Kettunen <jami.kettunen@protonmail.com>");
|
||||
MODULE_DESCRIPTION("DRM driver for Samsung S6E3FA5 AMOLED DSI cmd mode panel found on OnePlus 5 phones");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
343
drivers/gpu/drm/panel/panel-samsung-s6e3fc1.c
Normal file
343
drivers/gpu/drm/panel/panel-samsung-s6e3fc1.c
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2021 Jami Kettunen <jami.kettunen@protonmail.com>
|
||||
* Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/swab.h>
|
||||
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
struct s6e3fc1 {
|
||||
struct drm_panel panel;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator *supply;
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline struct s6e3fc1 *to_s6e3fc1_panel(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct s6e3fc1, panel);
|
||||
}
|
||||
|
||||
#define dsi_dcs_write_seq(dsi, seq...) do { \
|
||||
static const u8 d[] = { seq }; \
|
||||
int ret; \
|
||||
ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
static void s6e3fc1_reset(struct s6e3fc1 *ctx)
|
||||
{
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
}
|
||||
|
||||
static int s6e3fc1_on(struct s6e3fc1 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(25);
|
||||
|
||||
ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set tear on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsi_dcs_write_seq(dsi, 0xfc, 0x5a, 0x5a);
|
||||
dsi_dcs_write_seq(dsi, 0xe8, 0x64, 0x08, 0x0c);
|
||||
dsi_dcs_write_seq(dsi, 0xfc, 0xa5, 0xa5);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a);
|
||||
dsi_dcs_write_seq(dsi, 0xb0, 0x01);
|
||||
dsi_dcs_write_seq(dsi, 0xed, 0x04);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0xa5, 0xa5);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_off(struct s6e3fc1 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_off(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display off: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(160);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fc1 *ctx = to_s6e3fc1_panel(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_enable(ctx->supply);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
s6e3fc1_reset(ctx);
|
||||
|
||||
ret = s6e3fc1_on(ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
regulator_disable(ctx->supply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->prepared = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fc1 *ctx = to_s6e3fc1_panel(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = s6e3fc1_off(ctx);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
regulator_disable(ctx->supply);
|
||||
|
||||
ctx->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode s6e3fc1_mode = {
|
||||
.clock = (1080 + 128 + 16 + 64) * (2160 + 18 + 2 + 4) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 128,
|
||||
.hsync_end = 1080 + 128 + 16,
|
||||
.htotal = 1080 + 128 + 16 + 64,
|
||||
.vdisplay = 2160,
|
||||
.vsync_start = 2160 + 18,
|
||||
.vsync_end = 2160 + 18 + 2,
|
||||
.vtotal = 2160 + 18 + 2 + 4,
|
||||
.width_mm = 68,
|
||||
.height_mm = 137,
|
||||
};
|
||||
|
||||
static int s6e3fc1_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &s6e3fc1_mode);
|
||||
if (!mode)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs s6e3fc1_panel_funcs = {
|
||||
.prepare = s6e3fc1_prepare,
|
||||
.unprepare = s6e3fc1_unprepare,
|
||||
.get_modes = s6e3fc1_get_modes,
|
||||
};
|
||||
|
||||
static int s6e3fc1_bl_update_status(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
brightness = (u16)backlight_get_brightness(bl);
|
||||
// This panel needs the high and low bytes swapped for the brightness value
|
||||
brightness = __swab16(brightness);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_bl_get_brightness(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// This panel needs the high and low bytes swapped for the brightness value
|
||||
brightness = __swab16(brightness);
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return brightness;
|
||||
}
|
||||
|
||||
static const struct backlight_ops s6e3fc1_bl_ops = {
|
||||
.update_status = s6e3fc1_bl_update_status,
|
||||
.get_brightness = s6e3fc1_bl_get_brightness,
|
||||
};
|
||||
|
||||
static struct backlight_device *
|
||||
s6e3fc1_create_backlight(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
const struct backlight_properties props = {
|
||||
.type = BACKLIGHT_RAW,
|
||||
.brightness = 1023,
|
||||
.max_brightness = 1023,
|
||||
};
|
||||
|
||||
return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
|
||||
&s6e3fc1_bl_ops, &props);
|
||||
}
|
||||
|
||||
static int s6e3fc1_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct s6e3fc1 *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->supply = devm_regulator_get(dev, "vddio");
|
||||
if (IS_ERR(ctx->supply))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->supply),
|
||||
"Failed to get vddio regulator\n");
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ctx->reset_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
|
||||
"Failed to get reset-gpios\n");
|
||||
|
||||
ctx->dsi = dsi;
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
|
||||
dsi->lanes = 4;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_HSE |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &s6e3fc1_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->panel.backlight = s6e3fc1_create_backlight(dsi);
|
||||
if (IS_ERR(ctx->panel.backlight))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
|
||||
"Failed to create backlight\n");
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
|
||||
drm_panel_remove(&ctx->panel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void s6e3fc1_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct s6e3fc1 *ctx = mipi_dsi_get_drvdata(dsi);
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_detach(dsi);
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
|
||||
|
||||
drm_panel_remove(&ctx->panel);
|
||||
}
|
||||
|
||||
static const struct of_device_id s6e3fc1_of_match[] = {
|
||||
{ .compatible = "samsung,s6e3fc1" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, s6e3fc1_of_match);
|
||||
|
||||
static struct mipi_dsi_driver s6e3fc1_driver = {
|
||||
.probe = s6e3fc1_probe,
|
||||
.remove = s6e3fc1_remove,
|
||||
.driver = {
|
||||
.name = "panel-samsung-s6e3fc1",
|
||||
.of_match_table = s6e3fc1_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(s6e3fc1_driver);
|
||||
|
||||
MODULE_AUTHOR("Jami Kettunen <jami.kettunen@protonmail.com>");
|
||||
MODULE_DESCRIPTION("DRM driver for Samsung S6E3FC1 AMOLED DSI cmd mode panel found on OnePlus 5T phones");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
@ -39,6 +39,8 @@
|
|||
#define QUP_MX_READ_CNT 0x208
|
||||
#define QUP_IN_FIFO_BASE 0x218
|
||||
#define QUP_I2C_CLK_CTL 0x400
|
||||
#define QUP_I2C_CLK_CTL_SDA_NR GENMASK(27, 26)
|
||||
#define QUP_I2C_CLK_CTL_SCL_NR GENMASK(25, 24)
|
||||
#define QUP_I2C_STATUS 0x404
|
||||
#define QUP_I2C_MASTER_GEN 0x408
|
||||
|
||||
|
|
@ -1663,6 +1665,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
|
|||
int ret, fs_div, hs_div;
|
||||
u32 src_clk_freq = DEFAULT_SRC_CLK;
|
||||
u32 clk_freq = DEFAULT_CLK_FREQ;
|
||||
u32 noise_reject_scl = 0, noise_reject_sda = 0;
|
||||
int blocks;
|
||||
bool is_qup_v1;
|
||||
|
||||
|
|
@ -1860,6 +1863,19 @@ nodma:
|
|||
qup->clk_ctl = ((fs_div / 2) << 16) | (hs_div << 8) | (fs_div & 0xff);
|
||||
}
|
||||
|
||||
/* SCL/SDA Noise rejection (optional) */
|
||||
ret = device_property_read_u32(qup->dev, "qcom,noise-reject-scl",
|
||||
&noise_reject_scl);
|
||||
if (ret == 0)
|
||||
qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SCL_NR,
|
||||
noise_reject_scl);
|
||||
|
||||
ret = device_property_read_u32(qup->dev, "qcom,noise-reject-sda",
|
||||
&noise_reject_sda);
|
||||
if (ret == 0)
|
||||
qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SDA_NR,
|
||||
noise_reject_sda);
|
||||
|
||||
/*
|
||||
* Time it takes for a byte to be clocked out on the bus.
|
||||
* Each byte takes 9 clock cycles (8 bits + 1 ack).
|
||||
|
|
|
|||
|
|
@ -246,6 +246,19 @@ config KEYBOARD_GPIO
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called gpio_keys.
|
||||
|
||||
config KEYBOARD_GPIO_FASTMATRIX
|
||||
tristate "GPIO Keyboard"
|
||||
depends on GPIOLIB
|
||||
select INPUT_MATRIXKMAP
|
||||
help
|
||||
This driver implements support for matrix keypads and/or
|
||||
keyboards connected directly to GPIO pins of a CPU, made
|
||||
to also perform with slow I2C GPIO expanders and even
|
||||
on matrices with no protection diodes.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called gpio_fastmatrix
|
||||
|
||||
config KEYBOARD_GPIO_POLLED
|
||||
tristate "Polled GPIO buttons"
|
||||
depends on GPIOLIB
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ obj-$(CONFIG_KEYBOARD_DLINK_DIR685) += dlink-dir685-touchkeys.o
|
|||
obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_GOLDFISH_EVENTS) += goldfish_events.o
|
||||
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
|
||||
obj-$(CONFIG_KEYBOARD_GPIO_FASTMATRIX) += gpio_fastmatrix.o
|
||||
obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o
|
||||
obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_TCA8418) += tca8418_keypad.o
|
||||
|
|
|
|||
528
drivers/input/keyboard/gpio_fastmatrix.c
Normal file
528
drivers/input/keyboard/gpio_fastmatrix.c
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Fast GPIO driven keyboard/keypad matrix driver
|
||||
*
|
||||
* Copyright (c) 2020 AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
* Based on matrix_keypad.c
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
struct gpio_keyboard {
|
||||
struct device *dev;
|
||||
struct input_dev *input_dev;
|
||||
unsigned int row_shift;
|
||||
|
||||
struct gpio_descs *row_gpios;
|
||||
struct gpio_descs *col_gpios;
|
||||
u32 autorescan_ms;
|
||||
u32 debounce_ms;
|
||||
u32 col_scan_us;
|
||||
int clustered_irq;
|
||||
|
||||
DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
|
||||
|
||||
u32 last_key_state[MATRIX_MAX_COLS];
|
||||
struct delayed_work work;
|
||||
struct mutex lock;
|
||||
|
||||
bool drive_inactive_cols;
|
||||
bool gpio_all_disabled;
|
||||
bool scan_pending;
|
||||
bool stopped;
|
||||
};
|
||||
|
||||
static int activate_one_column(struct gpio_keyboard *gkb, int col, bool wait)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = gpiod_direction_output(gkb->col_gpios->desc[col], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (wait && gkb->col_scan_us)
|
||||
udelay(gkb->col_scan_us);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: If drive_inactive_cols is false, then the GPIO has to be put into
|
||||
* HiZ when de-activated to cause minmal side effect when scanning other
|
||||
* columns. In that case it is configured here to be input, otherwise it is
|
||||
* driven with the inactive value.
|
||||
*/
|
||||
static int deactivate_one_column(struct gpio_keyboard *gkb, int col)
|
||||
{
|
||||
gpiod_set_value_cansleep(gkb->col_gpios->desc[col], 0);
|
||||
if (!gkb->drive_inactive_cols)
|
||||
return gpiod_direction_input(gkb->col_gpios->desc[col]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int activate_all_cols(struct gpio_keyboard *gkb)
|
||||
{
|
||||
unsigned long val = ULONG_MAX;
|
||||
int ret, col;
|
||||
|
||||
/*
|
||||
* Shortcut! If we don't have to set direction, we can use
|
||||
* the way faster gpiod array setting instead.
|
||||
*/
|
||||
if (gkb->drive_inactive_cols) {
|
||||
return gpiod_set_array_value_cansleep(gkb->col_gpios->ndescs,
|
||||
gkb->col_gpios->desc,
|
||||
gkb->col_gpios->info,
|
||||
&val);
|
||||
}
|
||||
|
||||
for (col = 0; col < gkb->col_gpios->ndescs; col++) {
|
||||
ret = activate_one_column(gkb, col, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deactivate_all_cols(struct gpio_keyboard *gkb)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
int col, ret;
|
||||
|
||||
/*
|
||||
* If the GPIO controller supports setting all pins at once it
|
||||
* is going to be way faster, otherwise this function will fall
|
||||
* back to setting all pins one at a time.
|
||||
*/
|
||||
ret = gpiod_set_array_value_cansleep(gkb->col_gpios->ndescs,
|
||||
gkb->col_gpios->desc,
|
||||
gkb->col_gpios->info, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!gkb->drive_inactive_cols) {
|
||||
for (col = 0; col < gkb->col_gpios->ndescs; col++)
|
||||
gpiod_direction_input(gkb->col_gpios->desc[col]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void enable_row_irqs(struct gpio_keyboard *gkb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (gkb->clustered_irq > 0)
|
||||
enable_irq(gkb->clustered_irq);
|
||||
else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++)
|
||||
enable_irq(gpiod_to_irq(gkb->row_gpios->desc[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void disable_row_irqs(struct gpio_keyboard *gkb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (gkb->clustered_irq > 0)
|
||||
disable_irq_nosync(gkb->clustered_irq);
|
||||
else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++)
|
||||
disable_irq_nosync(gpiod_to_irq(gkb->row_gpios->desc[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets the keys from keyboard and reports it to input subsystem
|
||||
*/
|
||||
static void gpio_keyboard_scan(struct work_struct *work)
|
||||
{
|
||||
struct gpio_keyboard *gkb =
|
||||
container_of(work, struct gpio_keyboard, work.work);
|
||||
struct input_dev *input_dev = gkb->input_dev;
|
||||
const unsigned short *keycodes = input_dev->keycode;
|
||||
u32 *new_state;
|
||||
unsigned long row_values;
|
||||
int ret, row, col, code;
|
||||
u32 keymask = 0;
|
||||
|
||||
new_state = kzalloc(gkb->col_gpios->ndescs * sizeof(*new_state),
|
||||
GFP_KERNEL);
|
||||
if (!new_state)
|
||||
return;
|
||||
|
||||
/* de-activate all columns for scanning */
|
||||
deactivate_all_cols(gkb);
|
||||
|
||||
/* assert each column and read the row status out */
|
||||
for (col = 0; col < gkb->col_gpios->ndescs; col++) {
|
||||
activate_one_column(gkb, col, true);
|
||||
|
||||
ret = gpiod_get_array_value_cansleep(gkb->row_gpios->ndescs,
|
||||
gkb->row_gpios->desc,
|
||||
gkb->row_gpios->info,
|
||||
&row_values);
|
||||
new_state[col] = row_values;
|
||||
keymask |= new_state[col];
|
||||
|
||||
if (deactivate_one_column(gkb, col)) {
|
||||
activate_all_cols(gkb);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
activate_all_cols(gkb);
|
||||
|
||||
for (col = 0; col < gkb->col_gpios->ndescs; col++) {
|
||||
u32 bits_changed = gkb->last_key_state[col] ^ new_state[col];
|
||||
if (bits_changed == 0)
|
||||
continue;
|
||||
|
||||
for (row = 0; bits_changed; row++, bits_changed >>=1 ) {
|
||||
if (!(bits_changed & BIT(0)))
|
||||
continue;
|
||||
|
||||
code = MATRIX_SCAN_CODE(row, col, gkb->row_shift);
|
||||
input_event(input_dev, EV_MSC, MSC_SCAN, code);
|
||||
input_report_key(input_dev, keycodes[code],
|
||||
new_state[col] & (1 << row));
|
||||
}
|
||||
}
|
||||
input_sync(input_dev);
|
||||
|
||||
memcpy(gkb->last_key_state, new_state, sizeof(gkb->last_key_state));
|
||||
kfree(new_state);
|
||||
|
||||
/* Avoid missing key release events on quirky hardware */
|
||||
if (gkb->autorescan_ms && keymask) {
|
||||
queue_delayed_work(system_highpri_wq, &gkb->work,
|
||||
msecs_to_jiffies(gkb->autorescan_ms));
|
||||
return;
|
||||
}
|
||||
end:
|
||||
/* Enable IRQs again */
|
||||
mutex_lock(&gkb->lock);
|
||||
gkb->scan_pending = false;
|
||||
enable_row_irqs(gkb);
|
||||
mutex_unlock(&gkb->lock);
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_keyboard_interrupt(int irq, void *id)
|
||||
{
|
||||
struct gpio_keyboard *gkb = id;
|
||||
|
||||
/*
|
||||
* See if another IRQ beaten us to it and scheduled the
|
||||
* scan already. In that case we should not try to
|
||||
* disable IRQs again.
|
||||
*/
|
||||
if (unlikely(gkb->scan_pending || gkb->stopped))
|
||||
goto out;
|
||||
|
||||
mutex_lock(&gkb->lock);
|
||||
|
||||
disable_row_irqs(gkb);
|
||||
gkb->scan_pending = true;
|
||||
mod_delayed_work(system_highpri_wq, &gkb->work,
|
||||
msecs_to_jiffies(gkb->debounce_ms));
|
||||
|
||||
out:
|
||||
mutex_unlock(&gkb->lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int gpio_keyboard_start(struct input_dev *dev)
|
||||
{
|
||||
struct gpio_keyboard *gkb = input_get_drvdata(dev);
|
||||
|
||||
gkb->stopped = false;
|
||||
|
||||
/*
|
||||
* Schedule an immediate key scan to capture current key state;
|
||||
* columns will be activated and IRQs be enabled after the scan.
|
||||
*/
|
||||
schedule_delayed_work(&gkb->work, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gpio_keyboard_stop(struct input_dev *dev)
|
||||
{
|
||||
struct gpio_keyboard *gkb = input_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&gkb->lock);
|
||||
gkb->stopped = true;
|
||||
mutex_unlock(&gkb->lock);
|
||||
|
||||
flush_delayed_work(&gkb->work);
|
||||
/*
|
||||
* gpio_keyboard_scan() will leave IRQs enabled;
|
||||
* we should disable them now.
|
||||
*/
|
||||
disable_row_irqs(gkb);
|
||||
}
|
||||
|
||||
static void __maybe_unused gpio_keyboard_wakeup_en(struct gpio_keyboard *gkb)
|
||||
{
|
||||
int irq, i;
|
||||
|
||||
if (gkb->clustered_irq > 0) {
|
||||
if (enable_irq_wake(gkb->clustered_irq) == 0)
|
||||
gkb->gpio_all_disabled = true;
|
||||
} else {
|
||||
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++) {
|
||||
if (!test_bit(i, gkb->disabled_gpios)) {
|
||||
irq = gpiod_to_irq(gkb->row_gpios->desc[i]);
|
||||
|
||||
if (enable_irq_wake(irq) == 0)
|
||||
__set_bit(i, gkb->disabled_gpios);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __maybe_unused gpio_keyboard_wakeup_dis(struct gpio_keyboard *gkb)
|
||||
{
|
||||
int irq, i;
|
||||
|
||||
if (gkb->clustered_irq > 0) {
|
||||
if (gkb->gpio_all_disabled) {
|
||||
disable_irq_wake(gkb->clustered_irq);
|
||||
gkb->gpio_all_disabled = false;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++) {
|
||||
if (test_and_clear_bit(i, gkb->disabled_gpios)) {
|
||||
irq = gpiod_to_irq(gkb->row_gpios->desc[i]);
|
||||
disable_irq_wake(irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int __maybe_unused gpio_keyboard_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct gpio_keyboard *gkb = platform_get_drvdata(pdev);
|
||||
|
||||
gpio_keyboard_stop(gkb->input_dev);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
gpio_keyboard_wakeup_en(gkb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused gpio_keyboard_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct gpio_keyboard *gkb = platform_get_drvdata(pdev);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
gpio_keyboard_wakeup_dis(gkb);
|
||||
|
||||
gpio_keyboard_start(gkb->input_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static SIMPLE_DEV_PM_OPS(gpio_keyboard_pm_ops,
|
||||
gpio_keyboard_suspend, gpio_keyboard_resume);
|
||||
|
||||
static int gpio_keyboard_init_gpio(struct platform_device *pdev,
|
||||
struct gpio_keyboard *gkb)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (gkb->clustered_irq > 0) {
|
||||
ret = devm_request_threaded_irq(gkb->dev, gkb->clustered_irq,
|
||||
NULL, gpio_keyboard_interrupt,
|
||||
IRQF_ONESHOT, "gpio-keyboard", gkb);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Cannot get IRQ %d\n", gkb->clustered_irq);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++) {
|
||||
ret = devm_request_threaded_irq(
|
||||
gkb->dev,
|
||||
gpiod_to_irq(gkb->row_gpios->desc[i]),
|
||||
NULL, gpio_keyboard_interrupt,
|
||||
IRQF_TRIGGER_HIGH |
|
||||
IRQF_TRIGGER_LOW,
|
||||
"gpio-keyboard", gkb);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Cannot get IRQ for gpio%d\n",
|
||||
desc_to_gpio(gkb->row_gpios->desc[i]));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* initialized as disabled - enabled by input->open */
|
||||
disable_row_irqs(gkb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_keyboard_parse_dt(struct gpio_keyboard *gkb)
|
||||
{
|
||||
struct device *dev = gkb->dev;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Get as GPIOD_ASIS to use the configuration that comes from
|
||||
* device-tree. Anyway, in many cases the row is configured as
|
||||
* input, while the column is configured as output-high.
|
||||
*
|
||||
* This may vary depending on the hardware.
|
||||
*/
|
||||
gkb->row_gpios = devm_gpiod_get_array(dev, "row", GPIOD_ASIS);
|
||||
if (IS_ERR(gkb->row_gpios))
|
||||
return PTR_ERR(gkb->row_gpios);
|
||||
|
||||
gkb->col_gpios = devm_gpiod_get_array(dev, "col", GPIOD_ASIS);
|
||||
if (IS_ERR(gkb->col_gpios))
|
||||
return PTR_ERR(gkb->col_gpios);
|
||||
|
||||
/* All of these additional properties are optional */
|
||||
device_property_read_string(dev, "label", &gkb->input_dev->name);
|
||||
|
||||
if (device_property_read_bool(dev, "autorepeat"))
|
||||
__set_bit(EV_REP, gkb->input_dev->evbit);
|
||||
|
||||
gkb->drive_inactive_cols =
|
||||
device_property_read_bool(dev, "drive-inactive-cols");
|
||||
|
||||
rc = device_property_read_u32(dev, "autorescan-ms",
|
||||
&gkb->autorescan_ms);
|
||||
if (rc < 0)
|
||||
gkb->autorescan_ms = 0;
|
||||
|
||||
rc = device_property_read_u32(dev, "debounce-delay-ms",
|
||||
&gkb->debounce_ms);
|
||||
if (rc < 0)
|
||||
gkb->debounce_ms = 0;
|
||||
|
||||
rc = device_property_read_u32(dev, "col-scan-delay-us",
|
||||
&gkb->col_scan_us);
|
||||
if (rc < 0)
|
||||
gkb->col_scan_us = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_keyboard_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_keyboard *gkb;
|
||||
bool wake;
|
||||
int irq, ret;
|
||||
|
||||
gkb = devm_kmalloc(&pdev->dev, sizeof(*gkb), GFP_KERNEL);
|
||||
if (!gkb)
|
||||
return -ENOMEM;
|
||||
|
||||
gkb->dev = &pdev->dev;
|
||||
gkb->input_dev = devm_input_allocate_device(&pdev->dev);
|
||||
if (!gkb->input_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = gpio_keyboard_parse_dt(gkb);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
irq = platform_get_irq_optional(pdev, 0);
|
||||
gkb->clustered_irq = (irq > 0) ? irq : 0;
|
||||
gkb->row_shift = get_count_order(gkb->col_gpios->ndescs);
|
||||
gkb->stopped = true;
|
||||
INIT_DELAYED_WORK(&gkb->work, gpio_keyboard_scan);
|
||||
memset(gkb->last_key_state, 0, sizeof(gkb->last_key_state));
|
||||
mutex_init(&gkb->lock);
|
||||
|
||||
if (!gkb->input_dev->name)
|
||||
gkb->input_dev->name = pdev->name;
|
||||
gkb->input_dev->id.bustype = BUS_HOST;
|
||||
gkb->input_dev->dev.parent = &pdev->dev;
|
||||
gkb->input_dev->open = gpio_keyboard_start;
|
||||
gkb->input_dev->close = gpio_keyboard_stop;
|
||||
|
||||
ret = matrix_keypad_build_keymap(NULL, NULL,
|
||||
gkb->row_gpios->ndescs,
|
||||
gkb->col_gpios->ndescs,
|
||||
NULL, gkb->input_dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to build keymap\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
input_set_capability(gkb->input_dev, EV_MSC, MSC_SCAN);
|
||||
input_set_drvdata(gkb->input_dev, gkb);
|
||||
|
||||
ret = gpio_keyboard_init_gpio(pdev, gkb);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = input_register_device(gkb->input_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wake = device_property_read_bool(&pdev->dev, "wakeup-source");
|
||||
device_init_wakeup(&pdev->dev, wake);
|
||||
|
||||
platform_set_drvdata(pdev, gkb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_keyboard_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_keyboard *gkb = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
if (gkb->clustered_irq > 0) {
|
||||
free_irq(gkb->clustered_irq, gkb);
|
||||
} else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++)
|
||||
free_irq(gpiod_to_irq(gkb->row_gpios->desc[i]), gkb);
|
||||
}
|
||||
input_unregister_device(gkb->input_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id gpio_keyboard_dt_match[] = {
|
||||
{ .compatible = "gpio-fastmatrix-keyboard" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gpio_keyboard_dt_match);
|
||||
|
||||
static struct platform_driver gpio_keyboard_driver = {
|
||||
.probe = gpio_keyboard_probe,
|
||||
.remove = gpio_keyboard_remove,
|
||||
.driver = {
|
||||
.name = "gpio-fastmatrix-keyboard",
|
||||
.pm = &gpio_keyboard_pm_ops,
|
||||
.of_match_table = gpio_keyboard_dt_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(gpio_keyboard_driver);
|
||||
|
||||
MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
|
||||
MODULE_DESCRIPTION("Fast GPIO driven keyboard/keypad matrix driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:gpio-fastmatrix-keyboard");
|
||||
|
|
@ -186,6 +186,21 @@ config INPUT_PMIC8XXX_PWRKEY
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called pmic8xxx-pwrkey.
|
||||
|
||||
config INPUT_QCOM_PMI8998_HAPTICS
|
||||
tristate "Qualcomm SPMI HAPTICS"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on MFD_PM8XXX || MFD_SPMI_PMIC || COMPILE_TEST
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
This option enables support for the haptics found in pmi8998 and
|
||||
related PMICs. Based on the ff-memless interface.
|
||||
|
||||
This driver is for hardware too new for the INPUT_PM8XXX_VIBRATOR
|
||||
driver.
|
||||
|
||||
To compile this driver as module, choose M here: the
|
||||
module will be called qcom_pmi8998_haptics.
|
||||
|
||||
config INPUT_SPARCSPKR
|
||||
tristate "SPARC Speaker support"
|
||||
depends on PCI && SPARC64
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o
|
|||
obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
|
||||
obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o
|
||||
obj-$(CONFIG_INPUT_PWM_VIBRA) += pwm-vibra.o
|
||||
obj-$(CONFIG_INPUT_QCOM_PMI8998_HAPTICS)+= qcom-pmi8998-haptics.o
|
||||
obj-$(CONFIG_INPUT_RAVE_SP_PWRBUTTON) += rave-sp-pwrbutton.o
|
||||
obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
|
||||
obj-$(CONFIG_INPUT_REGULATOR_HAPTIC) += regulator-haptic.o
|
||||
|
|
|
|||
690
drivers/input/misc/qcom-pmi8998-haptics.c
Normal file
690
drivers/input/misc/qcom-pmi8998-haptics.c
Normal file
|
|
@ -0,0 +1,690 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2022, Caleb Connolly <caleb@connolly.tech>
|
||||
* Qualcomm QPMI haptics driver for pmi8998 and related PMICs.
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
// clang-format off
|
||||
#define HAP_STATUS_1_REG 0x0A
|
||||
#define HAP_BUSY_BIT BIT(1)
|
||||
#define SC_FLAG_BIT BIT(3)
|
||||
#define AUTO_RES_ERROR_BIT BIT(4)
|
||||
|
||||
#define HAP_LRA_AUTO_RES_LO_REG 0x0B
|
||||
#define HAP_LRA_AUTO_RES_HI_REG 0x0C
|
||||
|
||||
#define HAP_EN_CTL_REG 0x46
|
||||
#define HAP_EN_BIT BIT(7)
|
||||
|
||||
#define HAP_EN_CTL2_REG 0x48
|
||||
#define BRAKE_EN_BIT BIT(0)
|
||||
|
||||
#define HAP_AUTO_RES_CTRL_REG 0x4B
|
||||
#define AUTO_RES_EN_BIT BIT(7)
|
||||
#define AUTO_RES_ERR_RECOVERY_BIT BIT(3)
|
||||
#define AUTO_RES_EN_FLAG_BIT BIT(0)
|
||||
|
||||
#define HAP_CFG1_REG 0x4C
|
||||
#define HAP_ACT_TYPE_MASK BIT(0)
|
||||
|
||||
#define HAP_CFG2_REG 0x4D
|
||||
#define HAP_LRA_RES_TYPE_MASK BIT(0)
|
||||
|
||||
#define HAP_SEL_REG 0x4E
|
||||
#define HAP_WF_SOURCE_MASK GENMASK(5, 4)
|
||||
#define HAP_WF_SOURCE_SHIFT 4
|
||||
|
||||
#define HAP_LRA_AUTO_RES_REG 0x4F
|
||||
#define LRA_AUTO_RES_MODE_MASK GENMASK(6, 4)
|
||||
#define LRA_AUTO_RES_MODE_SHIFT 4
|
||||
#define LRA_HIGH_Z_MASK GENMASK(3, 2)
|
||||
#define LRA_HIGH_Z_SHIFT 2
|
||||
#define LRA_RES_CAL_MASK GENMASK(1, 0)
|
||||
#define HAP_RES_CAL_PERIOD_MIN 4
|
||||
#define HAP_RES_CAL_PERIOD_MAX 32
|
||||
|
||||
#define HAP_VMAX_CFG_REG 0x51
|
||||
#define HAP_VMAX_OVD_BIT BIT(6)
|
||||
#define HAP_VMAX_MASK GENMASK(5, 1)
|
||||
#define HAP_VMAX_SHIFT 1
|
||||
|
||||
#define HAP_ILIM_CFG_REG 0x52
|
||||
#define HAP_ILIM_SEL_MASK BIT(0)
|
||||
#define HAP_ILIM_400_MA 0
|
||||
#define HAP_ILIM_800_MA 1
|
||||
|
||||
#define HAP_SC_DEB_REG 0x53
|
||||
#define HAP_SC_DEB_MASK GENMASK(2, 0)
|
||||
#define HAP_SC_DEB_CYCLES_MIN 0
|
||||
#define HAP_DEF_SC_DEB_CYCLES 8
|
||||
#define HAP_SC_DEB_CYCLES_MAX 32
|
||||
|
||||
#define HAP_RATE_CFG1_REG 0x54
|
||||
#define HAP_RATE_CFG1_MASK GENMASK(7, 0)
|
||||
#define HAP_RATE_CFG2_SHIFT 8 // As CFG2 is the most significant byte
|
||||
|
||||
#define HAP_RATE_CFG2_REG 0x55
|
||||
#define HAP_RATE_CFG2_MASK GENMASK(3, 0)
|
||||
|
||||
#define HAP_SC_CLR_REG 0x59
|
||||
#define SC_CLR_BIT BIT(0)
|
||||
|
||||
#define HAP_BRAKE_REG 0x5C
|
||||
#define HAP_BRAKE_PAT_MASK 0x3
|
||||
|
||||
#define HAP_WF_REPEAT_REG 0x5E
|
||||
#define WF_REPEAT_MASK GENMASK(6, 4)
|
||||
#define WF_REPEAT_SHIFT 4
|
||||
#define WF_REPEAT_MIN 1
|
||||
#define WF_REPEAT_MAX 128
|
||||
#define WF_S_REPEAT_MASK GENMASK(1, 0)
|
||||
#define WF_S_REPEAT_MIN 1
|
||||
#define WF_S_REPEAT_MAX 8
|
||||
|
||||
#define HAP_WF_S1_REG 0x60
|
||||
#define HAP_WF_SIGN_BIT BIT(7)
|
||||
#define HAP_WF_OVD_BIT BIT(6)
|
||||
#define HAP_WF_SAMP_MAX GENMASK(5, 1)
|
||||
#define HAP_WF_SAMPLE_LEN 8
|
||||
|
||||
#define HAP_PLAY_REG 0x70
|
||||
#define HAP_PLAY_BIT BIT(7)
|
||||
#define HAP_PAUSE_BIT BIT(0)
|
||||
|
||||
#define HAP_SEC_ACCESS_REG 0xD0
|
||||
#define HAP_SEC_ACCESS_UNLOCK 0xA5
|
||||
|
||||
#define HAP_TEST2_REG 0xE3
|
||||
|
||||
|
||||
#define HAP_VMAX_MIN_MV 116
|
||||
#define HAP_VMAX_MAX_MV 3596
|
||||
#define HAP_VMAX_MAX_MV_STRONG 3596
|
||||
|
||||
#define HAP_WAVE_PLAY_RATE_MIN_US 0
|
||||
#define HAP_WAVE_PLAY_RATE_MAX_US 20475
|
||||
#define HAP_WAVE_PLAY_TIME_MAX_MS 15000
|
||||
|
||||
#define AUTO_RES_ERR_POLL_TIME_NS (20 * NSEC_PER_MSEC)
|
||||
#define HAPTICS_BACK_EMF_DELAY_US 20000
|
||||
|
||||
#define HAP_BRAKE_PAT_LEN 4
|
||||
#define HAP_WAVE_SAMP_LEN 8
|
||||
#define NUM_WF_SET 4
|
||||
#define HAP_WAVE_SAMP_SET_LEN (HAP_WAVE_SAMP_LEN * NUM_WF_SET)
|
||||
#define HAP_RATE_CFG_STEP_US 5
|
||||
|
||||
#define SC_MAX_COUNT 5
|
||||
#define SC_COUNT_RST_DELAY_US 1000000
|
||||
|
||||
// Actuator types
|
||||
#define HAP_TYPE_LRA 0
|
||||
#define HAP_TYPE_ERM 1
|
||||
|
||||
// LRA Wave type
|
||||
#define HAP_WAVE_SINE 0
|
||||
#define HAP_WAVE_SQUARE 1
|
||||
|
||||
// Play modes
|
||||
#define HAP_PLAY_DIRECT 0
|
||||
#define HAP_PLAY_BUFFER 1
|
||||
#define HAP_PLAY_AUDIO 2
|
||||
#define HAP_PLAY_PWM 3
|
||||
|
||||
#define HAP_PLAY_MAX HAP_PLAY_PWM
|
||||
|
||||
// Auto resonance type
|
||||
#define HAP_AUTO_RES_NONE 0
|
||||
#define HAP_AUTO_RES_ZXD 1
|
||||
#define HAP_AUTO_RES_QWD 2
|
||||
#define HAP_AUTO_RES_MAX_QWD 3
|
||||
#define HAP_AUTO_RES_ZXD_EOP 4
|
||||
// clang-format on
|
||||
|
||||
static const uint8_t default_brake_pattern[] = {
|
||||
0x3, 0x3, 0x3, 0x3, 0x3,
|
||||
};
|
||||
|
||||
static const uint8_t wave_sample_pattern[] = {
|
||||
0x7e, 0x7e, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct spmi_haptics - struct for spmi haptics data.
|
||||
*
|
||||
* @dev: Our device parent.
|
||||
* @regmap: Register map for the hardware block.
|
||||
* @input: The input device used to receive events.
|
||||
* @work: Work struct to play effects.
|
||||
* @base: Base address of the regmap.
|
||||
* @play_irq: Fired to load the next wave pattern.
|
||||
* @sc_irq: Short circuit irq.
|
||||
* @last_sc_time: Time since the short circuit IRQ last fired.
|
||||
* @sc_count: Number of times the short circuit IRQ has fired in this interval.
|
||||
* @actuator_type: The type of actuator in use.
|
||||
* @wave_shape: The shape of the waves to use (sine or square).
|
||||
* @play_mode: The play mode to use (direct, buffer, pwm, audio).
|
||||
* @vmax: Max voltage to use when playing.
|
||||
* @current_limit: The current limit for this hardware (400mA or 800mA).
|
||||
* @play_wave_rate: The wave rate to use for this hardware.
|
||||
* @play_lock: Lock to be held when updating the hardware state.
|
||||
*/
|
||||
struct spmi_haptics {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct input_dev *input;
|
||||
struct work_struct work;
|
||||
uint32_t base;
|
||||
|
||||
int play_irq;
|
||||
int sc_irq;
|
||||
ktime_t last_sc_time;
|
||||
uint8_t sc_count;
|
||||
|
||||
uint8_t actuator_type;
|
||||
uint8_t wave_shape;
|
||||
uint8_t play_mode;
|
||||
uint32_t vmax;
|
||||
uint32_t current_limit;
|
||||
uint32_t play_wave_rate;
|
||||
struct mutex play_lock;
|
||||
};
|
||||
|
||||
static int haptics_write_vmax(struct spmi_haptics *haptics)
|
||||
{
|
||||
uint8_t val = 0;
|
||||
uint32_t vmax_mv = haptics->vmax;
|
||||
|
||||
vmax_mv = clamp_t(uint32_t, vmax_mv, HAP_VMAX_MIN_MV, HAP_VMAX_MAX_MV);
|
||||
vmax_mv = DIV_ROUND_CLOSEST(vmax_mv, HAP_VMAX_MIN_MV);
|
||||
|
||||
val = FIELD_PREP(HAP_VMAX_MASK, vmax_mv);
|
||||
|
||||
return regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_VMAX_CFG_REG,
|
||||
HAP_VMAX_MASK | HAP_WF_OVD_BIT, val);
|
||||
}
|
||||
|
||||
static int haptics_module_enable(struct spmi_haptics *haptics, bool enable)
|
||||
{
|
||||
return regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_EN_CTL_REG, HAP_EN_BIT,
|
||||
enable ? HAP_EN_BIT : 0);
|
||||
}
|
||||
|
||||
static int haptics_play(struct spmi_haptics *haptics, bool play)
|
||||
{
|
||||
return regmap_update_bits(haptics->regmap, haptics->base + HAP_PLAY_REG,
|
||||
HAP_PLAY_BIT | HAP_PAUSE_BIT,
|
||||
play ? HAP_PLAY_BIT : 0);
|
||||
}
|
||||
|
||||
static bool is_haptics_module_enabled(struct spmi_haptics *haptics)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
regmap_read(haptics->regmap, haptics->base + HAP_EN_CTL_REG, &val);
|
||||
return !!val;
|
||||
}
|
||||
|
||||
/*
|
||||
* This IRQ is fired to tell us to load the next wave sample set.
|
||||
* As we only currently support a single sample set, it's unused.
|
||||
*/
|
||||
static irqreturn_t haptics_play_irq(int irq, void *data)
|
||||
{
|
||||
struct spmi_haptics *haptics = data;
|
||||
|
||||
dev_dbg(haptics->dev, "play_irq triggered");
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fires every ~50ms whilst the haptics are active.
|
||||
* If the SC_FLAG_BIT is set then that means there isn't a short circuit
|
||||
* and we just need to clear the IRQ to indicate that the device should
|
||||
* keep vibrating.
|
||||
*
|
||||
* Otherwise, it means a short circuit situation has occurred.
|
||||
*/
|
||||
static irqreturn_t haptics_sc_irq(int irq, void *data)
|
||||
{
|
||||
struct spmi_haptics *haptics = data;
|
||||
int ret;
|
||||
uint32_t val;
|
||||
long sc_delta_time_us;
|
||||
ktime_t temp;
|
||||
|
||||
mutex_lock(&haptics->play_lock);
|
||||
|
||||
ret = regmap_read(haptics->regmap, haptics->base + HAP_STATUS_1_REG,
|
||||
&val);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!(val & SC_FLAG_BIT)) {
|
||||
haptics->sc_count = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
temp = ktime_get();
|
||||
sc_delta_time_us = ktime_us_delta(temp, haptics->last_sc_time);
|
||||
haptics->last_sc_time = temp;
|
||||
|
||||
if (sc_delta_time_us > SC_COUNT_RST_DELAY_US)
|
||||
haptics->sc_count = 0;
|
||||
else
|
||||
haptics->sc_count++;
|
||||
|
||||
ret = regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_SC_CLR_REG, SC_CLR_BIT,
|
||||
SC_CLR_BIT);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (haptics->sc_count > SC_MAX_COUNT) {
|
||||
cancel_work_sync(&haptics->work);
|
||||
dev_err(haptics->dev,
|
||||
"Short circuit persists, disabling haptics\n");
|
||||
ret = haptics_module_enable(haptics, false);
|
||||
if (ret)
|
||||
dev_err(haptics->dev, "Error disabling module, rc=%d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&haptics->play_lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int haptics_vibrate(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (haptics->sc_count > SC_MAX_COUNT) {
|
||||
dev_err(haptics->dev, "Can't play while in short circuit");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = haptics_write_vmax(haptics);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = haptics_module_enable(haptics, true);
|
||||
if (ret) {
|
||||
dev_err(haptics->dev, "Error enabling module, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = haptics_play(haptics, true);
|
||||
if (ret) {
|
||||
dev_err(haptics->dev, "Error enabling play, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int haptics_stop_vibrate(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = haptics_play(haptics, false);
|
||||
if (ret) {
|
||||
dev_err(haptics->dev, "Error disabling play, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = haptics_module_enable(haptics, false);
|
||||
if (ret) {
|
||||
dev_err(haptics->dev, "Error disabling module, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void haptics_play_stop_work(struct work_struct *work)
|
||||
{
|
||||
struct spmi_haptics *haptics =
|
||||
container_of(work, struct spmi_haptics, work);
|
||||
|
||||
int ret;
|
||||
|
||||
mutex_lock(&haptics->play_lock);
|
||||
|
||||
if (!is_haptics_module_enabled(haptics) && haptics->vmax)
|
||||
ret = haptics_vibrate(haptics);
|
||||
else
|
||||
ret = haptics_stop_vibrate(haptics);
|
||||
if (ret)
|
||||
dev_err(haptics->dev, "Error setting haptics, ret=%d", ret);
|
||||
|
||||
mutex_unlock(&haptics->play_lock);
|
||||
}
|
||||
|
||||
static int spmi_haptics_play_effect(struct input_dev *dev, void *data,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
struct spmi_haptics *haptics = input_get_drvdata(dev);
|
||||
uint32_t magnitude;
|
||||
|
||||
dev_dbg(haptics->dev, "%s: Rumbling with strong: %d and weak: %d",
|
||||
__func__, effect->u.rumble.strong_magnitude,
|
||||
effect->u.rumble.weak_magnitude);
|
||||
|
||||
magnitude = effect->u.rumble.strong_magnitude >> 8;
|
||||
if (!magnitude)
|
||||
magnitude = effect->u.rumble.weak_magnitude >> 10;
|
||||
|
||||
if (!magnitude)
|
||||
haptics->vmax = 0;
|
||||
else
|
||||
haptics->vmax =
|
||||
((HAP_VMAX_MAX_MV - HAP_VMAX_MIN_MV) * magnitude) /
|
||||
100 +
|
||||
HAP_VMAX_MIN_MV;
|
||||
|
||||
schedule_work(&haptics->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_close - callback for input device close
|
||||
* @dev: input device pointer
|
||||
*
|
||||
* Turns off the vibrator.
|
||||
*/
|
||||
static void spmi_haptics_close(struct input_dev *dev)
|
||||
{
|
||||
struct spmi_haptics *haptics = input_get_drvdata(dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
haptics->vmax = 0;
|
||||
|
||||
if (is_haptics_module_enabled(haptics))
|
||||
haptics_stop_vibrate(haptics);
|
||||
}
|
||||
|
||||
static int haptics_write_brake_pattern(struct spmi_haptics *haptics,
|
||||
const uint8_t *brake_pattern)
|
||||
{
|
||||
int ret, i;
|
||||
uint8_t val = 0;
|
||||
|
||||
for (i = HAP_BRAKE_PAT_LEN - 1; i >= 0; i--)
|
||||
val |= FIELD_PREP(HAP_BRAKE_PAT_MASK, brake_pattern[i])
|
||||
<< (i * 2);
|
||||
|
||||
ret = regmap_update_bits(haptics->regmap, haptics->base + HAP_BRAKE_REG,
|
||||
0xff, val);
|
||||
|
||||
return ret ?:
|
||||
regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_EN_CTL2_REG,
|
||||
BRAKE_EN_BIT, BRAKE_EN_BIT);
|
||||
}
|
||||
|
||||
static int haptics_init(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
uint8_t val, mask;
|
||||
uint16_t play_rate;
|
||||
|
||||
ret = regmap_update_bits(haptics->regmap, haptics->base + HAP_CFG1_REG,
|
||||
HAP_ACT_TYPE_MASK, haptics->actuator_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Configure auto resonance
|
||||
* see qpnp_haptics_lra_auto_res_config downstream
|
||||
* This is greatly simplified.
|
||||
*/
|
||||
val = FIELD_PREP(LRA_RES_CAL_MASK, ilog2(32 / HAP_RES_CAL_PERIOD_MIN)) |
|
||||
FIELD_PREP(LRA_AUTO_RES_MODE_MASK, HAP_AUTO_RES_ZXD_EOP) |
|
||||
FIELD_PREP(LRA_HIGH_Z_MASK, 1);
|
||||
mask = LRA_AUTO_RES_MODE_MASK | LRA_HIGH_Z_MASK | LRA_RES_CAL_MASK;
|
||||
|
||||
ret = regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_LRA_AUTO_RES_REG, mask,
|
||||
val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = FIELD_PREP(HAP_WF_SOURCE_MASK, haptics->play_mode);
|
||||
ret = regmap_update_bits(haptics->regmap, haptics->base + HAP_SEL_REG,
|
||||
HAP_WF_SOURCE_MASK, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_ILIM_CFG_REG,
|
||||
HAP_ILIM_SEL_MASK, haptics->current_limit);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Configure the debounce for short-circuit detection. */
|
||||
ret = regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_SC_DEB_REG,
|
||||
HAP_SC_DEB_MASK, HAP_SC_DEB_CYCLES_MAX);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(haptics->regmap, haptics->base + HAP_CFG2_REG,
|
||||
HAP_LRA_RES_TYPE_MASK, haptics->wave_shape);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Configure RATE_CFG1 and RATE_CFG2 registers.
|
||||
* Note: For ERM (unsupported) these registers act as play rate and
|
||||
* for LRA these represent resonance period
|
||||
*/
|
||||
play_rate = haptics->play_wave_rate / HAP_RATE_CFG_STEP_US;
|
||||
val = FIELD_PREP(HAP_RATE_CFG1_MASK, play_rate);
|
||||
ret = regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_RATE_CFG1_REG,
|
||||
HAP_RATE_CFG1_MASK, val);
|
||||
val = FIELD_PREP(HAP_RATE_CFG2_MASK, play_rate >> 8);
|
||||
ret = ret ?:
|
||||
regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_RATE_CFG2_REG,
|
||||
HAP_RATE_CFG1_MASK, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = haptics_write_brake_pattern(haptics, default_brake_pattern);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Currently this is the only supported play mode */
|
||||
if (haptics->play_mode == HAP_PLAY_BUFFER) {
|
||||
/* zero repeats and zero sample repeats */
|
||||
val = FIELD_PREP(WF_REPEAT_MASK, 0) |
|
||||
FIELD_PREP(WF_S_REPEAT_MASK, 0);
|
||||
ret = regmap_update_bits(haptics->regmap,
|
||||
haptics->base + HAP_WF_REPEAT_REG,
|
||||
WF_REPEAT_MASK | WF_S_REPEAT_MASK,
|
||||
val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_bulk_write(haptics->regmap,
|
||||
haptics->base + HAP_WF_S1_REG,
|
||||
wave_sample_pattern, HAP_WAVE_SAMP_LEN);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spmi_haptics_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct spmi_haptics *haptics;
|
||||
struct input_dev *input_dev;
|
||||
int ret, irq;
|
||||
|
||||
haptics = devm_kzalloc(&pdev->dev, sizeof(*haptics), GFP_KERNEL);
|
||||
if (!haptics)
|
||||
return -ENOMEM;
|
||||
|
||||
haptics->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!haptics->regmap)
|
||||
return -ENODEV;
|
||||
|
||||
haptics->dev = &pdev->dev;
|
||||
|
||||
platform_set_drvdata(pdev, haptics);
|
||||
|
||||
ret = device_property_read_u32(haptics->dev, "reg", &haptics->base);
|
||||
if (ret)
|
||||
return dev_err_probe(haptics->dev, ret,
|
||||
"Couldn't read base address");
|
||||
|
||||
/* This is the only currently supported configuration, these values
|
||||
* are left to allow future additions
|
||||
*/
|
||||
haptics->actuator_type = HAP_TYPE_LRA;
|
||||
haptics->play_mode = HAP_PLAY_BUFFER;
|
||||
haptics->wave_shape = HAP_WAVE_SINE;
|
||||
haptics->current_limit = HAP_ILIM_400_MA;
|
||||
|
||||
ret = device_property_read_u32(haptics->dev, "qcom,wave-play-rate-us",
|
||||
&haptics->play_wave_rate);
|
||||
if (ret)
|
||||
return dev_err_probe(haptics->dev, ret,
|
||||
"qcom,wave-play-rate-us is required\n");
|
||||
|
||||
INIT_WORK(&haptics->work, haptics_play_stop_work);
|
||||
|
||||
ret = haptics_init(haptics);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
input_dev = devm_input_allocate_device(&pdev->dev);
|
||||
if (!input_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
input_dev->name = "spmi_haptics";
|
||||
input_dev->id.version = 1;
|
||||
input_dev->close = spmi_haptics_close;
|
||||
input_set_drvdata(input_dev, haptics);
|
||||
|
||||
haptics->input = input_dev;
|
||||
|
||||
/* In the future this should become FF_PERIODIC */
|
||||
input_set_capability(haptics->input, EV_FF, FF_RUMBLE);
|
||||
|
||||
ret = input_ff_create_memless(input_dev, NULL,
|
||||
spmi_haptics_play_effect);
|
||||
if (ret)
|
||||
return dev_err_probe(
|
||||
&pdev->dev, ret,
|
||||
"Couldn't register haptics as EV_FF device\n");
|
||||
|
||||
ret = input_register_device(input_dev);
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"Couldn't register input device\n");
|
||||
|
||||
/* NOTE: the play IRQ is only used for buffer mode */
|
||||
irq = platform_get_irq_byname(pdev, "play");
|
||||
if (irq < 0) {
|
||||
return dev_err_probe(&pdev->dev, irq,
|
||||
"Unable to get play irq\n");
|
||||
}
|
||||
ret = devm_request_threaded_irq(haptics->dev, irq, NULL,
|
||||
haptics_play_irq, IRQF_ONESHOT,
|
||||
"haptics_play_irq", haptics);
|
||||
if (ret)
|
||||
return dev_err_probe(haptics->dev, ret,
|
||||
"Couldn't request play irq\n");
|
||||
|
||||
irq = platform_get_irq_byname(pdev, "short");
|
||||
if (irq < 0)
|
||||
return dev_err_probe(&pdev->dev, irq,
|
||||
"Unable to get short circut irq\n");
|
||||
ret = devm_request_threaded_irq(haptics->dev, irq, NULL, haptics_sc_irq,
|
||||
IRQF_ONESHOT, "haptics_short_irq",
|
||||
haptics);
|
||||
if (ret)
|
||||
return dev_err_probe(haptics->dev, ret,
|
||||
"Couldn't request short circuit irq\n");
|
||||
|
||||
mutex_init(&haptics->play_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused spmi_haptics_suspend(struct device *dev)
|
||||
{
|
||||
struct spmi_haptics *haptics = dev_get_drvdata(dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
haptics_stop_vibrate(haptics);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(spmi_haptics_pm_ops, spmi_haptics_suspend, NULL);
|
||||
|
||||
static int spmi_haptics_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spmi_haptics *haptics = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
mutex_destroy(&haptics->play_lock);
|
||||
input_unregister_device(haptics->input);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spmi_haptics_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct spmi_haptics *haptics = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
haptics_stop_vibrate(haptics);
|
||||
}
|
||||
|
||||
static const struct of_device_id spmi_haptics_match_table[] = {
|
||||
{ .compatible = "qcom,pmi8998-haptics" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, spmi_haptics_match_table);
|
||||
|
||||
static struct platform_driver spmi_haptics_driver = {
|
||||
.probe = spmi_haptics_probe,
|
||||
.remove = spmi_haptics_remove,
|
||||
.shutdown = spmi_haptics_shutdown,
|
||||
.driver = {
|
||||
.name = "spmi-haptics",
|
||||
.pm = &spmi_haptics_pm_ops,
|
||||
.of_match_table = spmi_haptics_match_table,
|
||||
},
|
||||
};
|
||||
module_platform_driver(spmi_haptics_driver);
|
||||
|
||||
MODULE_DESCRIPTION("spmi haptics driver using ff-memless framework");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Caleb Connolly <caleb@connolly.tech>");
|
||||
|
|
@ -82,6 +82,14 @@ config RMI4_F12
|
|||
touchpads. For sensors that support relative pointing, F12 also
|
||||
provides mouse input.
|
||||
|
||||
config RMI4_F1A
|
||||
bool "RMI4 Function 1A (Simple capacitive buttons)"
|
||||
depends on OF
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 1A.
|
||||
|
||||
Function 1A provides GPIO capacitive button support for RMI4 devices.
|
||||
|
||||
config RMI4_F30
|
||||
bool "RMI4 Function 30 (GPIO LED)"
|
||||
help
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
|
|||
rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o
|
||||
rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
|
||||
rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
|
||||
rmi_core-$(CONFIG_RMI4_F1A) += rmi_f1a.o
|
||||
rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
|
||||
rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
|
||||
rmi_core-$(CONFIG_RMI4_F3A) += rmi_f3a.o
|
||||
|
|
|
|||
|
|
@ -360,6 +360,9 @@ static struct rmi_function_handler *fn_handlers[] = {
|
|||
#ifdef CONFIG_RMI4_F12
|
||||
&rmi_f12_handler,
|
||||
#endif
|
||||
#ifdef CONFIG_RMI4_F1A
|
||||
&rmi_f1a_handler,
|
||||
#endif
|
||||
#ifdef CONFIG_RMI4_F30
|
||||
&rmi_f30_handler,
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ extern struct rmi_function_handler rmi_f01_handler;
|
|||
extern struct rmi_function_handler rmi_f03_handler;
|
||||
extern struct rmi_function_handler rmi_f11_handler;
|
||||
extern struct rmi_function_handler rmi_f12_handler;
|
||||
extern struct rmi_function_handler rmi_f1a_handler;
|
||||
extern struct rmi_function_handler rmi_f30_handler;
|
||||
extern struct rmi_function_handler rmi_f34_handler;
|
||||
extern struct rmi_function_handler rmi_f3a_handler;
|
||||
|
|
|
|||
190
drivers/input/rmi4/rmi_f1a.c
Normal file
190
drivers/input/rmi4/rmi_f1a.c
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
// FIXME: Too much stuff is hardcoded in currently!
|
||||
#include <linux/input.h>
|
||||
#include <linux/rmi.h>
|
||||
#include <linux/of.h>
|
||||
#include "rmi_driver.h"
|
||||
|
||||
/* Query 1 */
|
||||
//#define F1A_BUTTONS_COUNT 0b00011111 /* BIT(1) */
|
||||
|
||||
#define MAX_NAME_LEN 256
|
||||
#define F1A_MAX_BUTTONS 8
|
||||
|
||||
struct f1a_data {
|
||||
struct rmi_function *fn;
|
||||
|
||||
unsigned char button_count;
|
||||
u32 button_map[F1A_MAX_BUTTONS];
|
||||
struct input_dev *input;
|
||||
char input_name[MAX_NAME_LEN];
|
||||
char input_phys[MAX_NAME_LEN];
|
||||
u8 button_data_buffer;
|
||||
};
|
||||
|
||||
static int rmi_f1a_initialize(struct f1a_data *f1a)
|
||||
{
|
||||
struct rmi_function *fn = f1a->fn;
|
||||
struct device *dev = &fn->dev;
|
||||
//u8 query[2];
|
||||
int error;
|
||||
|
||||
/*error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, query, 2);
|
||||
if (error) {
|
||||
dev_err(dev, "Failed to read query register (%d).\n", error);
|
||||
return error;
|
||||
}
|
||||
printk("%s: query0: 0x%x, query1: 0x%x\n", __func__, query[0], query[1]);*/
|
||||
|
||||
error = of_property_read_variable_u32_array(dev_of_node(dev),
|
||||
"syna,codes", f1a->button_map, 1, F1A_MAX_BUTTONS);
|
||||
if (error < 0) {
|
||||
dev_err(dev, "Failed to parse syna,codes from OF device tree (%d).\n", error);
|
||||
return error;
|
||||
}
|
||||
// FIXME: button_count = query[1] & F1A_BUTTONS_COUNT;
|
||||
f1a->button_count = 0;
|
||||
for (f1a->button_count = 0; f1a->button_count < F1A_MAX_BUTTONS; f1a->button_count++)
|
||||
if (f1a->button_map[f1a->button_count] == 0)
|
||||
break;
|
||||
rmi_dbg(RMI_DEBUG_FN, dev, "%s: %d button codes defined\n", __func__, f1a->button_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f1a_register_device(struct f1a_data *f1a)
|
||||
{
|
||||
struct rmi_function *fn = f1a->fn;
|
||||
struct device *dev = &fn->dev;
|
||||
struct rmi_device *rmi_dev = fn->rmi_dev;
|
||||
struct input_dev *input_dev;
|
||||
int i, rc;
|
||||
|
||||
input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
dev_err(dev, "Failed to allocate input device.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
f1a->input = input_dev;
|
||||
snprintf(f1a->input_name, MAX_NAME_LEN, "%s.fn%02x",
|
||||
dev_name(&rmi_dev->dev), fn->fd.function_number);
|
||||
input_dev->name = f1a->input_name;
|
||||
snprintf(f1a->input_phys, MAX_NAME_LEN, "%s/input0", input_dev->name);
|
||||
input_dev->phys = f1a->input_phys;
|
||||
input_dev->dev.parent = &rmi_dev->dev;
|
||||
input_set_drvdata(input_dev, f1a);
|
||||
|
||||
/* set up any input events */
|
||||
set_bit(EV_SYN, input_dev->evbit);
|
||||
set_bit(EV_KEY, input_dev->evbit);
|
||||
|
||||
/* manage button map using input subsystem */
|
||||
input_dev->keycode = f1a->button_map;
|
||||
input_dev->keycodesize = sizeof(f1a->button_map); /* f1a->button_count */
|
||||
input_dev->keycodemax = f1a->button_count;
|
||||
|
||||
/* set bits for each button */
|
||||
for (i = 0; i < f1a->button_count; i++) {
|
||||
set_bit(f1a->button_map[i], input_dev->keybit);
|
||||
input_set_capability(input_dev, EV_KEY, f1a->button_map[i]);
|
||||
}
|
||||
|
||||
rc = input_register_device(input_dev);
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "Failed to register input device.\n");
|
||||
goto error_free_device;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_free_device:
|
||||
input_free_device(input_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int rmi_f1a_probe(struct rmi_function *fn)
|
||||
{
|
||||
struct device *dev = &fn->dev;
|
||||
struct f1a_data *f1a;
|
||||
int error;
|
||||
|
||||
rmi_dbg(RMI_DEBUG_FN, dev, "%s\n", __func__);
|
||||
|
||||
if (!fn->dev.of_node) {
|
||||
/*
|
||||
* Some quirky devices (e.g. OnePlus 5T) report supporting F1A
|
||||
* (Simple capacitive buttons) despite not having the hardware,
|
||||
* so in case there isn't an associated device-tree node present
|
||||
* just pretend we probed successfully.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
f1a = devm_kzalloc(dev, sizeof(struct f1a_data), GFP_KERNEL);
|
||||
if (!f1a)
|
||||
return -ENOMEM;
|
||||
|
||||
f1a->fn = fn;
|
||||
|
||||
error = rmi_f1a_initialize(f1a);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
error = rmi_f1a_register_device(f1a);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
dev_set_drvdata(dev, f1a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f1a_config(struct rmi_function *fn)
|
||||
{
|
||||
fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn->irq_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t rmi_f1a_attention(int irq, void *ctx)
|
||||
{
|
||||
struct rmi_function *fn = ctx;
|
||||
struct device *dev = &fn->dev;
|
||||
struct rmi_device *rmi_dev = fn->rmi_dev;
|
||||
struct f1a_data *f1a = dev_get_drvdata(dev);
|
||||
int error, button;
|
||||
|
||||
// TODO: use rmi_read_block() to accomodate up to 8 buttons?
|
||||
error = rmi_read(rmi_dev, fn->fd.data_base_addr, &(f1a->button_data_buffer));
|
||||
if (error < 0) {
|
||||
dev_err(dev, "Failed to read button data registers (%d).\n", error);
|
||||
return error;
|
||||
}
|
||||
/*rmi_dbg(RMI_DEBUG_FN, dev, "%s: button_data=0x%x\n", __func__, f1a->button_data_buffer);*/
|
||||
|
||||
/* generate events for buttons that change state */
|
||||
// TODO: Implement button_data_buffer as array + button_reg = button / 8
|
||||
for (button = 0; button < f1a->button_count; button++) {
|
||||
int button_shift;
|
||||
bool button_status;
|
||||
/* bit shift to get button's status */
|
||||
button_shift = button % 8;
|
||||
button_status = ((f1a->button_data_buffer >> button_shift) & 0x01) != 0;
|
||||
|
||||
rmi_dbg(RMI_DEBUG_FN, dev, "button %d (code %d) -> %d\n",
|
||||
button, f1a->button_map[button], button_status);
|
||||
/* generate an event here */
|
||||
input_report_key(f1a->input, f1a->button_map[button], button_status);
|
||||
}
|
||||
input_sync(f1a->input); /* sync after groups of events */
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
struct rmi_function_handler rmi_f1a_handler = {
|
||||
.driver = {
|
||||
.name = "rmi4_f1a",
|
||||
},
|
||||
.func = 0x1a,
|
||||
.probe = rmi_f1a_probe,
|
||||
.config = rmi_f1a_config,
|
||||
.attention = rmi_f1a_attention,
|
||||
};
|
||||
|
|
@ -44,6 +44,15 @@ config INTERCONNECT_QCOM_MSM8996
|
|||
This is a driver for the Qualcomm Network-on-Chip on msm8996-based
|
||||
platforms.
|
||||
|
||||
config INTERCONNECT_QCOM_MSM8998
|
||||
tristate "Qualcomm MSM8998 interconnect driver"
|
||||
depends on INTERCONNECT_QCOM
|
||||
depends on QCOM_SMD_RPM
|
||||
select INTERCONNECT_QCOM_SMD_RPM
|
||||
help
|
||||
This is a driver for the Qualcomm Network-on-Chip on msm8998-based
|
||||
platforms.
|
||||
|
||||
config INTERCONNECT_QCOM_OSM_L3
|
||||
tristate "Qualcomm OSM L3 interconnect driver"
|
||||
depends on INTERCONNECT_QCOM || COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ qnoc-msm8916-objs := msm8916.o
|
|||
qnoc-msm8939-objs := msm8939.o
|
||||
qnoc-msm8974-objs := msm8974.o
|
||||
qnoc-msm8996-objs := msm8996.o
|
||||
qnoc-msm8998-objs := msm8998.o
|
||||
icc-osm-l3-objs := osm-l3.o
|
||||
qnoc-qcm2290-objs := qcm2290.o
|
||||
qnoc-qcs404-objs := qcs404.o
|
||||
|
|
@ -32,6 +33,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += qnoc-msm8916.o
|
|||
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8939) += qnoc-msm8939.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8996) += qnoc-msm8996.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8998) += qnoc-msm8998.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_QCM2290) += qnoc-qcm2290.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
|
||||
|
|
|
|||
983
drivers/interconnect/qcom/msm8998.c
Normal file
983
drivers/interconnect/qcom/msm8998.c
Normal file
|
|
@ -0,0 +1,983 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Qualcomm MSM8998 Network-on-Chip (NoC) QoS driver
|
||||
* Copyright (c) 2020, AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
* Copyright (C) 2020, Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interconnect/qcom,msm8998.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interconnect-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "smd-rpm.h"
|
||||
|
||||
#define RPM_BUS_MASTER_REQ 0x73616d62
|
||||
#define RPM_BUS_SLAVE_REQ 0x766c7362
|
||||
|
||||
/* BIMC QoS */
|
||||
#define M_BKE_REG_BASE(n) (0x300 + (0x4000 * n))
|
||||
#define M_BKE_EN_ADDR(n) (M_BKE_REG_BASE(n))
|
||||
#define M_BKE_HEALTH_CFG_ADDR(i, n) (M_BKE_REG_BASE(n) + 0x40 + (0x4 * i))
|
||||
|
||||
#define M_BKE_HEALTH_CFG_LIMITCMDS_MASK 0x80000000
|
||||
#define M_BKE_HEALTH_CFG_AREQPRIO_MASK 0x300
|
||||
#define M_BKE_HEALTH_CFG_PRIOLVL_MASK 0x3
|
||||
#define M_BKE_HEALTH_CFG_AREQPRIO_SHIFT 0x8
|
||||
#define M_BKE_HEALTH_CFG_LIMITCMDS_SHIFT 0x1f
|
||||
|
||||
#define M_BKE_EN_EN_BMASK 0x1
|
||||
|
||||
/* Valid for both NoC and BIMC */
|
||||
#define NOC_QOS_MODE_FIXED 0x0
|
||||
#define NOC_QOS_MODE_LIMITER 0x1
|
||||
#define NOC_QOS_MODE_BYPASS 0x2
|
||||
|
||||
/* NoC QoS */
|
||||
#define NOC_PERM_MODE_FIXED 1
|
||||
#define NOC_PERM_MODE_BYPASS (1 << NOC_QOS_MODE_BYPASS)
|
||||
|
||||
#define NOC_QOS_PRIORITYn_ADDR(n) (0x8 + (n * 0x1000))
|
||||
#define NOC_QOS_PRIORITY_MASK 0xf
|
||||
#define NOC_QOS_PRIORITY_P1_SHIFT 0x2
|
||||
#define NOC_QOS_PRIORITY_P0_SHIFT 0x3
|
||||
|
||||
#define NOC_QOS_MODEn_ADDR(n) (0xc + (n * 0x1000))
|
||||
#define NOC_QOS_MODEn_MASK 0x3
|
||||
|
||||
enum {
|
||||
MSM8998_MASTER_IPA = 1,
|
||||
MSM8998_MASTER_CNOC_A2NOC,
|
||||
MSM8998_MASTER_SDCC_2,
|
||||
MSM8998_MASTER_SDCC_4,
|
||||
MSM8998_MASTER_BLSP_1,
|
||||
MSM8998_MASTER_BLSP_2,
|
||||
MSM8998_MASTER_UFS,
|
||||
MSM8998_MASTER_USB_HS,
|
||||
MSM8998_MASTER_USB3,
|
||||
MSM8998_MASTER_CRYPTO_C0,
|
||||
MSM8998_MASTER_GNOC_BIMC,
|
||||
MSM8998_MASTER_OXILI,
|
||||
MSM8998_MASTER_MNOC_BIMC,
|
||||
MSM8998_MASTER_SNOC_BIMC,
|
||||
MSM8998_MASTER_PIMEM,
|
||||
MSM8998_MASTER_SNOC_CNOC,
|
||||
MSM8998_MASTER_QDSS_DAP,
|
||||
MSM8998_MASTER_APPS_PROC,
|
||||
MSM8998_MASTER_CNOC_MNOC_MMSS_CFG,
|
||||
MSM8998_MASTER_CNOC_MNOC_CFG,
|
||||
MSM8998_MASTER_CPP,
|
||||
MSM8998_MASTER_JPEG,
|
||||
MSM8998_MASTER_MDP_P0,
|
||||
MSM8998_MASTER_MDP_P1,
|
||||
MSM8998_MASTER_VENUS,
|
||||
MSM8998_MASTER_VFE,
|
||||
MSM8998_MASTER_QDSS_ETR,
|
||||
MSM8998_MASTER_QDSS_BAM,
|
||||
MSM8998_MASTER_SNOC_CFG,
|
||||
MSM8998_MASTER_BIMC_SNOC,
|
||||
MSM8998_MASTER_A1NOC_SNOC,
|
||||
MSM8998_MASTER_A2NOC_SNOC,
|
||||
MSM8998_MASTER_GNOC_SNOC,
|
||||
MSM8998_MASTER_PCIE_0,
|
||||
MSM8998_MASTER_A2NOC_TSIF,
|
||||
MSM8998_MASTER_CRVIRT_A2NOC,
|
||||
MSM8998_MASTER_ROTATOR,
|
||||
MSM8998_MASTER_VENUS_VMEM,
|
||||
MSM8998_MASTER_HMSS,
|
||||
MSM8998_MASTER_BIMC_SNOC_0,
|
||||
MSM8998_MASTER_BIMC_SNOC_1,
|
||||
|
||||
MSM8998_SLAVE_A1NOC_SNOC,
|
||||
MSM8998_SLAVE_A2NOC_SNOC,
|
||||
MSM8998_SLAVE_EBI,
|
||||
MSM8998_SLAVE_HMSS_L3,
|
||||
MSM8998_SLAVE_CNOC_A2NOC,
|
||||
MSM8998_SLAVE_MPM,
|
||||
MSM8998_SLAVE_PMIC_ARB,
|
||||
MSM8998_SLAVE_TLMM_NORTH,
|
||||
MSM8998_SLAVE_TCSR,
|
||||
MSM8998_SLAVE_PIMEM_CFG,
|
||||
MSM8998_SLAVE_IMEM_CFG,
|
||||
MSM8998_SLAVE_MESSAGE_RAM,
|
||||
MSM8998_SLAVE_GLM,
|
||||
MSM8998_SLAVE_BIMC_CFG,
|
||||
MSM8998_SLAVE_PRNG,
|
||||
MSM8998_SLAVE_SPDM,
|
||||
MSM8998_SLAVE_QDSS_CFG,
|
||||
MSM8998_SLAVE_CNOC_MNOC_CFG,
|
||||
MSM8998_SLAVE_SNOC_CFG,
|
||||
MSM8998_SLAVE_QM_CFG,
|
||||
MSM8998_SLAVE_CLK_CTL,
|
||||
MSM8998_SLAVE_MSS_CFG,
|
||||
MSM8998_SLAVE_UFS_CFG,
|
||||
MSM8998_SLAVE_A2NOC_CFG,
|
||||
MSM8998_SLAVE_A2NOC_SMMU_CFG,
|
||||
MSM8998_SLAVE_GPUSS_CFG,
|
||||
MSM8998_SLAVE_AHB2PHY,
|
||||
MSM8998_SLAVE_BLSP_1,
|
||||
MSM8998_SLAVE_SDCC_2,
|
||||
MSM8998_SLAVE_SDCC_4,
|
||||
MSM8998_SLAVE_BLSP_2,
|
||||
MSM8998_SLAVE_PDM,
|
||||
MSM8998_SLAVE_CNOC_MNOC_MMSS_CFG,
|
||||
MSM8998_SLAVE_USB_HS,
|
||||
MSM8998_SLAVE_USB3_0,
|
||||
MSM8998_SLAVE_SRVC_CNOC,
|
||||
MSM8998_SLAVE_GNOC_BIMC,
|
||||
MSM8998_SLAVE_GNOC_SNOC,
|
||||
MSM8998_SLAVE_CAMERA_CFG,
|
||||
MSM8998_SLAVE_CAMERA_THROTTLE_CFG,
|
||||
MSM8998_SLAVE_MISC_CFG,
|
||||
MSM8998_SLAVE_VENUS_THROTTLE_CFG,
|
||||
MSM8998_SLAVE_VENUS_CFG,
|
||||
MSM8998_SLAVE_MMSS_CLK_XPU_CFG,
|
||||
MSM8998_SLAVE_MMSS_CLK_CFG,
|
||||
MSM8998_SLAVE_MNOC_MPU_CFG,
|
||||
MSM8998_SLAVE_DISPLAY_CFG,
|
||||
MSM8998_SLAVE_CSI_PHY_CFG,
|
||||
MSM8998_SLAVE_DISPLAY_THROTTLE_CFG,
|
||||
MSM8998_SLAVE_SMMU_CFG,
|
||||
MSM8998_SLAVE_MNOC_BIMC,
|
||||
MSM8998_SLAVE_SRVC_MNOC,
|
||||
MSM8998_SLAVE_HMSS,
|
||||
MSM8998_SLAVE_LPASS,
|
||||
MSM8998_SLAVE_WLAN,
|
||||
MSM8998_SLAVE_CDSP,
|
||||
MSM8998_SLAVE_IPA,
|
||||
MSM8998_SLAVE_SNOC_BIMC,
|
||||
MSM8998_SLAVE_SNOC_CNOC,
|
||||
MSM8998_SLAVE_IMEM,
|
||||
MSM8998_SLAVE_PIMEM,
|
||||
MSM8998_SLAVE_QDSS_STM,
|
||||
MSM8998_SLAVE_SRVC_SNOC,
|
||||
MSM8998_SLAVE_BIMC_SNOC_0,
|
||||
MSM8998_SLAVE_BIMC_SNOC_1,
|
||||
MSM8998_SLAVE_SSC_CFG,
|
||||
MSM8998_SLAVE_SKL,
|
||||
MSM8998_SLAVE_TLMM_WEST,
|
||||
MSM8998_SLAVE_A1NOC_CFG,
|
||||
MSM8998_SLAVE_A1NOC_SMMU_CFG,
|
||||
MSM8998_SLAVE_TSIF,
|
||||
MSM8998_SLAVE_TLMM_EAST,
|
||||
MSM8998_SLAVE_CRVIRT_A2NOC,
|
||||
MSM8998_SLAVE_VMEM_CFG,
|
||||
MSM8998_SLAVE_VMEM,
|
||||
MSM8998_SLAVE_PCIE_0,
|
||||
};
|
||||
|
||||
#define to_qcom_provider(_provider) \
|
||||
container_of(_provider, struct qcom_icc_provider, provider)
|
||||
|
||||
static const struct clk_bulk_data bus_clocks[] = {
|
||||
{ .id = "bus" },
|
||||
{ .id = "bus_a" },
|
||||
};
|
||||
|
||||
static const struct clk_bulk_data bus_mm_clocks[] = {
|
||||
{ .id = "bus" },
|
||||
{ .id = "bus_a" },
|
||||
{ .id = "iface" },
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qcom_icc_provider - Qualcomm specific interconnect provider
|
||||
* @provider: generic interconnect provider
|
||||
* @bus_clks: the clk_bulk_data table of bus clocks
|
||||
* @num_clks: the total number of clk_bulk_data entries
|
||||
* @is_bimc_node: indicates whether to use bimc specific setting
|
||||
* @mmio: NoC base iospace
|
||||
*/
|
||||
struct qcom_icc_provider {
|
||||
struct icc_provider provider;
|
||||
struct clk_bulk_data *bus_clks;
|
||||
int num_clks;
|
||||
bool is_bimc_node;
|
||||
struct regmap *regmap;
|
||||
void __iomem *mmio;
|
||||
};
|
||||
|
||||
#define MSM8998_MAX_LINKS 38
|
||||
|
||||
/**
|
||||
* struct qcom_icc_qos - Qualcomm specific interconnect QoS parameters
|
||||
* @areq_prio: node requests priority
|
||||
* @prio_level: priority level for bus communication
|
||||
* @limit_commands: activate/deactivate limiter mode during runtime
|
||||
* @ap_owned: indicates if the node is owned by the AP or by the RPM
|
||||
* @qos_mode: default qos mode for this node
|
||||
* @qos_port: qos port number for finding qos registers of this node
|
||||
*/
|
||||
struct qcom_icc_qos {
|
||||
u32 areq_prio;
|
||||
u32 prio_level;
|
||||
bool limit_commands;
|
||||
bool ap_owned;
|
||||
int qos_mode;
|
||||
int qos_port;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qcom_icc_node - Qualcomm specific interconnect nodes
|
||||
* @name: the node name used in debugfs
|
||||
* @id: a unique node identifier
|
||||
* @links: an array of nodes where we can go next while traversing
|
||||
* @num_links: the total number of @links
|
||||
* @buswidth: width of the interconnect between a node and the bus (bytes)
|
||||
* @mas_rpm_id: RPM id for devices that are bus masters
|
||||
* @slv_rpm_id: RPM id for devices that are bus slaves
|
||||
* @qos: NoC QoS setting parameters
|
||||
* @rate: current bus clock rate in Hz
|
||||
*/
|
||||
struct qcom_icc_node {
|
||||
unsigned char *name;
|
||||
u16 id;
|
||||
u16 links[MSM8998_MAX_LINKS];
|
||||
u16 num_links;
|
||||
u16 buswidth;
|
||||
int mas_rpm_id;
|
||||
int slv_rpm_id;
|
||||
struct qcom_icc_qos qos;
|
||||
u64 rate;
|
||||
};
|
||||
|
||||
struct qcom_icc_desc {
|
||||
struct qcom_icc_node **nodes;
|
||||
size_t num_nodes;
|
||||
const struct regmap_config *regmap_cfg;
|
||||
};
|
||||
|
||||
#define DEFINE_QNODE(_name, _id, _buswidth, _mas_rpm_id, _slv_rpm_id, \
|
||||
_ap_owned, _qos_mode, _qos_prio, _qos_port, ...) \
|
||||
static struct qcom_icc_node _name = { \
|
||||
.name = #_name, \
|
||||
.id = _id, \
|
||||
.buswidth = _buswidth, \
|
||||
.mas_rpm_id = _mas_rpm_id, \
|
||||
.slv_rpm_id = _slv_rpm_id, \
|
||||
.qos.ap_owned = _ap_owned, \
|
||||
.qos.qos_mode = _qos_mode, \
|
||||
.qos.areq_prio = _qos_prio, \
|
||||
.qos.prio_level = _qos_prio, \
|
||||
.qos.qos_port = _qos_port, \
|
||||
.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })), \
|
||||
.links = { __VA_ARGS__ }, \
|
||||
}
|
||||
|
||||
/* masters */
|
||||
DEFINE_QNODE(mas_pcie_0, MSM8998_MASTER_PCIE_0, 16, 45, -1, true, NOC_QOS_MODE_FIXED, 1, 1, MSM8998_SLAVE_A1NOC_SNOC);
|
||||
DEFINE_QNODE(mas_usb3, MSM8998_MASTER_USB3, 16, 32, -1, true, NOC_QOS_MODE_FIXED, 1, 2, MSM8998_SLAVE_A1NOC_SNOC);
|
||||
DEFINE_QNODE(mas_ufs, MSM8998_MASTER_UFS, 16, 68, -1, true, NOC_QOS_MODE_FIXED, 1, 2, MSM8998_SLAVE_A1NOC_SNOC);
|
||||
DEFINE_QNODE(mas_blsp_2, MSM8998_MASTER_BLSP_2, 16, 39, -1, false, NOC_QOS_MODE_FIXED, 0, 4, MSM8998_SLAVE_A1NOC_SNOC);
|
||||
DEFINE_QNODE(mas_cnoc_a2noc, MSM8998_MASTER_CNOC_A2NOC, 8, 146, -1, true, -1, 0, -1, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_ipa, MSM8998_MASTER_IPA, 8, 59, -1, true, NOC_QOS_MODE_FIXED, 1, 1, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_sdcc_2, MSM8998_MASTER_SDCC_2, 8, 35, -1, false, NOC_QOS_MODE_FIXED, 0, 6, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_sdcc_4, MSM8998_MASTER_SDCC_4, 8, 36, -1, false, NOC_QOS_MODE_FIXED, 0, 7, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_tsif, MSM8998_MASTER_A2NOC_TSIF, 4, 37, -1, true, -1, 0, -1, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_blsp_1, MSM8998_MASTER_BLSP_1, 16, 41, -1, false, NOC_QOS_MODE_FIXED, 0, 8, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_crvirt_a2noc, MSM8998_MASTER_CRVIRT_A2NOC, 8, 145, -1, false, NOC_QOS_MODE_FIXED, 0, 9, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_gnoc_bimc, MSM8998_MASTER_GNOC_BIMC, 8, 144, -1, true, NOC_QOS_MODE_FIXED, 0, 0, MSM8998_SLAVE_EBI, MSM8998_SLAVE_BIMC_SNOC_0);
|
||||
DEFINE_QNODE(mas_oxili, MSM8998_MASTER_OXILI, 8, 6, -1, true, NOC_QOS_MODE_BYPASS, 0, 1, MSM8998_SLAVE_BIMC_SNOC_1, MSM8998_SLAVE_HMSS_L3, MSM8998_SLAVE_EBI, MSM8998_SLAVE_BIMC_SNOC_0);
|
||||
DEFINE_QNODE(mas_mnoc_bimc, MSM8998_MASTER_MNOC_BIMC, 8, 2, -1, true, NOC_QOS_MODE_BYPASS, 0, 2, MSM8998_SLAVE_BIMC_SNOC_1, MSM8998_SLAVE_HMSS_L3, MSM8998_SLAVE_EBI, MSM8998_SLAVE_BIMC_SNOC_0);
|
||||
DEFINE_QNODE(mas_snoc_bimc, MSM8998_MASTER_SNOC_BIMC, 8, 3, -1, false, NOC_QOS_MODE_BYPASS, 0, 3, MSM8998_SLAVE_HMSS_L3, MSM8998_SLAVE_EBI);
|
||||
DEFINE_QNODE(mas_snoc_cnoc, MSM8998_MASTER_SNOC_CNOC, 8, 52, -1, true, -1, 0, -1, MSM8998_SLAVE_SKL, MSM8998_SLAVE_BLSP_2, MSM8998_SLAVE_MESSAGE_RAM, MSM8998_SLAVE_TLMM_WEST, MSM8998_SLAVE_TSIF, MSM8998_SLAVE_MPM, MSM8998_SLAVE_BIMC_CFG, MSM8998_SLAVE_TLMM_EAST, MSM8998_SLAVE_SPDM, MSM8998_SLAVE_PIMEM_CFG, MSM8998_SLAVE_A1NOC_SMMU_CFG, MSM8998_SLAVE_BLSP_1, MSM8998_SLAVE_CLK_CTL, MSM8998_SLAVE_PRNG, MSM8998_SLAVE_USB3_0, MSM8998_SLAVE_QDSS_CFG, MSM8998_SLAVE_QM_CFG, MSM8998_SLAVE_A2NOC_CFG, MSM8998_SLAVE_PMIC_ARB, MSM8998_SLAVE_UFS_CFG, MSM8998_SLAVE_SRVC_CNOC, MSM8998_SLAVE_AHB2PHY, MSM8998_SLAVE_IPA, MSM8998_SLAVE_GLM, MSM8998_SLAVE_SNOC_CFG, MSM8998_SLAVE_SSC_CFG, MSM8998_SLAVE_SDCC_2, MSM8998_SLAVE_SDCC_4, MSM8998_SLAVE_PDM, MSM8998_SLAVE_CNOC_MNOC_MMSS_CFG, MSM8998_SLAVE_CNOC_MNOC_CFG, MSM8998_SLAVE_MSS_CFG, MSM8998_SLAVE_IMEM_CFG, MSM8998_SLAVE_A1NOC_CFG, MSM8998_SLAVE_GPUSS_CFG, MSM8998_SLAVE_TCSR, MSM8998_SLAVE_TLMM_NORTH);
|
||||
DEFINE_QNODE(mas_qdss_dap, MSM8998_MASTER_QDSS_DAP, 8, 49, -1, true, -1, 0, -1, MSM8998_SLAVE_SKL, MSM8998_SLAVE_BLSP_2, MSM8998_SLAVE_MESSAGE_RAM, MSM8998_SLAVE_TLMM_WEST, MSM8998_SLAVE_TSIF, MSM8998_SLAVE_MPM, MSM8998_SLAVE_BIMC_CFG, MSM8998_SLAVE_TLMM_EAST, MSM8998_SLAVE_SPDM, MSM8998_SLAVE_PIMEM_CFG, MSM8998_SLAVE_A1NOC_SMMU_CFG, MSM8998_SLAVE_BLSP_1, MSM8998_SLAVE_CLK_CTL, MSM8998_SLAVE_PRNG, MSM8998_SLAVE_USB3_0, MSM8998_SLAVE_QDSS_CFG, MSM8998_SLAVE_QM_CFG, MSM8998_SLAVE_A2NOC_CFG, MSM8998_SLAVE_PMIC_ARB, MSM8998_SLAVE_UFS_CFG, MSM8998_SLAVE_SRVC_CNOC, MSM8998_SLAVE_AHB2PHY, MSM8998_SLAVE_IPA, MSM8998_SLAVE_GLM, MSM8998_SLAVE_SNOC_CFG, MSM8998_SLAVE_SDCC_2, MSM8998_SLAVE_SDCC_4, MSM8998_SLAVE_PDM, MSM8998_SLAVE_CNOC_MNOC_MMSS_CFG, MSM8998_SLAVE_CNOC_MNOC_CFG, MSM8998_SLAVE_MSS_CFG, MSM8998_SLAVE_IMEM_CFG, MSM8998_SLAVE_A1NOC_CFG, MSM8998_SLAVE_GPUSS_CFG, MSM8998_SLAVE_SSC_CFG, MSM8998_SLAVE_TCSR, MSM8998_SLAVE_TLMM_NORTH, MSM8998_SLAVE_CNOC_A2NOC);
|
||||
DEFINE_QNODE(mas_crypto, MSM8998_MASTER_CRYPTO_C0, 650, 23, -1, false, -1, 0, -1, MSM8998_MASTER_CRVIRT_A2NOC);
|
||||
DEFINE_QNODE(mas_apss_proc, MSM8998_MASTER_APPS_PROC, 32, 0, -1, true, -1, 0, -1, MSM8998_SLAVE_GNOC_BIMC);
|
||||
DEFINE_QNODE(mas_cnoc_mnoc_mmss_cfg, MSM8998_MASTER_CNOC_MNOC_MMSS_CFG, 8, 4, -1, true, -1, 0, -1, MSM8998_SLAVE_CAMERA_THROTTLE_CFG, MSM8998_SLAVE_VENUS_CFG, MSM8998_SLAVE_MISC_CFG, MSM8998_SLAVE_CAMERA_CFG, MSM8998_SLAVE_DISPLAY_THROTTLE_CFG, MSM8998_SLAVE_VENUS_THROTTLE_CFG, MSM8998_SLAVE_DISPLAY_CFG, MSM8998_SLAVE_MMSS_CLK_CFG, MSM8998_SLAVE_VMEM_CFG, MSM8998_SLAVE_MMSS_CLK_XPU_CFG, MSM8998_SLAVE_SMMU_CFG);
|
||||
DEFINE_QNODE(mas_cnoc_mnoc_cfg, MSM8998_MASTER_CNOC_MNOC_CFG, 8, 5, -1, true, -1, 0, -1, MSM8998_SLAVE_SRVC_MNOC);
|
||||
DEFINE_QNODE(mas_cpp, MSM8998_MASTER_CPP, 32, 115, -1, true, NOC_QOS_MODE_BYPASS, 0, 5, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_jpeg, MSM8998_MASTER_JPEG, 32, 7, -1, true, NOC_QOS_MODE_BYPASS, 0, 7, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_mdp_p0, MSM8998_MASTER_MDP_P0, 32, 8, -1, true, NOC_QOS_MODE_BYPASS, 0, 1, MSM8998_SLAVE_MNOC_BIMC); /* vrail-comp???? */
|
||||
DEFINE_QNODE(mas_mdp_p1, MSM8998_MASTER_MDP_P1, 32, 61, -1, true, NOC_QOS_MODE_BYPASS, 0, 2, MSM8998_SLAVE_MNOC_BIMC); /* vrail-comp??? */
|
||||
DEFINE_QNODE(mas_rotator, MSM8998_MASTER_ROTATOR, 32, 120, -1, true, NOC_QOS_MODE_BYPASS, 0, 0, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_venus, MSM8998_MASTER_VENUS, 32, 9, -1, true, NOC_QOS_MODE_BYPASS, 0, 3, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_vfe, MSM8998_MASTER_VFE, 32, 11, -1, true, NOC_QOS_MODE_BYPASS, 0, 6, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_venus_vmem, MSM8998_MASTER_VENUS_VMEM, 32, 121, -1, true, -1, 0, -1, MSM8998_SLAVE_VMEM);
|
||||
DEFINE_QNODE(mas_hmss, MSM8998_MASTER_HMSS, 16, 118, -1, true, NOC_QOS_MODE_FIXED, 1, 3, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_SNOC_BIMC);
|
||||
DEFINE_QNODE(mas_qdss_bam, MSM8998_MASTER_QDSS_BAM, 16, 19, -1, true, NOC_QOS_MODE_FIXED, 1, 1, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_SNOC_BIMC);
|
||||
DEFINE_QNODE(mas_snoc_cfg, MSM8998_MASTER_SNOC_CFG, 16, 20, -1, false, -1, 0, -1, MSM8998_SLAVE_SRVC_SNOC);
|
||||
DEFINE_QNODE(mas_bimc_snoc_0, MSM8998_MASTER_BIMC_SNOC_0, 16, 21, -1, false, -1, 0, -1, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_LPASS, MSM8998_SLAVE_HMSS, MSM8998_SLAVE_WLAN, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_QDSS_STM);
|
||||
DEFINE_QNODE(mas_bimc_snoc_1, MSM8998_MASTER_BIMC_SNOC_1, 16, 109, -1, true, -1, 0, -1, MSM8998_SLAVE_PCIE_0);
|
||||
DEFINE_QNODE(mas_a1noc_snoc, MSM8998_MASTER_A1NOC_SNOC, 16, 111, -1, false, -1, 0, -1, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_PCIE_0, MSM8998_SLAVE_LPASS, MSM8998_SLAVE_HMSS, MSM8998_SLAVE_SNOC_BIMC, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_QDSS_STM);
|
||||
DEFINE_QNODE(mas_a2noc_snoc, MSM8998_MASTER_A2NOC_SNOC, 16, 112, -1, false, -1, 0, -1, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_PCIE_0, MSM8998_SLAVE_LPASS, MSM8998_SLAVE_HMSS, MSM8998_SLAVE_SNOC_BIMC, MSM8998_SLAVE_WLAN, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_QDSS_STM);
|
||||
DEFINE_QNODE(mas_qdss_etr, MSM8998_MASTER_QDSS_ETR, 16, 31, -1, true, NOC_QOS_MODE_FIXED, 1, 2, MSM8998_SLAVE_IMEM, MSM8998_MASTER_PIMEM, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_SNOC_BIMC);
|
||||
|
||||
/* slaves */
|
||||
DEFINE_QNODE(slv_a1noc_snoc, MSM8998_SLAVE_A1NOC_SNOC, 16, -1, 142, false, -1, 0, -1, MSM8998_MASTER_A1NOC_SNOC);
|
||||
DEFINE_QNODE(slv_a2noc_snoc, MSM8998_SLAVE_A2NOC_SNOC, 16, -1, 143, false, -1, 0, -1, MSM8998_MASTER_A2NOC_SNOC);
|
||||
DEFINE_QNODE(slv_ebi, MSM8998_SLAVE_EBI, 8, -1, 0, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_hmss_l3, MSM8998_SLAVE_HMSS_L3, 8, -1, 160, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_bimc_snoc_0, MSM8998_SLAVE_BIMC_SNOC_0, 8, -1, 2, false, -1, 0, -1, MSM8998_MASTER_BIMC_SNOC_0);
|
||||
DEFINE_QNODE(slv_bimc_snoc_1, MSM8998_SLAVE_BIMC_SNOC_1, 8, -1, 138, true, -1, 0, -1, MSM8998_MASTER_BIMC_SNOC_1);
|
||||
DEFINE_QNODE(slv_cnoc_a2noc, MSM8998_SLAVE_CNOC_A2NOC, 4, -1, 208, true, -1, 0, -1, MSM8998_MASTER_CNOC_A2NOC);
|
||||
DEFINE_QNODE(slv_ssc_cfg, MSM8998_SLAVE_SSC_CFG, 4, -1, 177, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mpm, MSM8998_SLAVE_MPM, 4, -1, 62, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pmic_arb, MSM8998_SLAVE_PMIC_ARB, 4, -1, 59, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tlmm_north, MSM8998_SLAVE_TLMM_NORTH, 4, -1, 214, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pimem_cfg, MSM8998_SLAVE_PIMEM_CFG, 4, -1, 167, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_imem_cfg, MSM8998_SLAVE_IMEM_CFG, 4, -1, 54, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_message_ram, MSM8998_SLAVE_MESSAGE_RAM, 4, -1, 55, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_skl, MSM8998_SLAVE_SKL, 4, -1, 196, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_bimc_cfg, MSM8998_SLAVE_BIMC_CFG, 4, -1, 56, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_prng, MSM8998_SLAVE_PRNG, 4, -1, 44, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_a2noc_cfg, MSM8998_SLAVE_A2NOC_CFG, 4, -1, 150, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_ipa, MSM8998_SLAVE_IPA, 4, -1, 183, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tcsr, MSM8998_SLAVE_TCSR, 4, -1, 50, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_snoc_cfg, MSM8998_SLAVE_SNOC_CFG, 4, -1, 70, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_clk_ctl, MSM8998_SLAVE_CLK_CTL, 4, -1, 47, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_glm, MSM8998_SLAVE_GLM, 4, -1, 209, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_spdm, MSM8998_SLAVE_SPDM, 4, -1, 60, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_gpuss_cfg, MSM8998_SLAVE_GPUSS_CFG, 4, -1, 11, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_cnoc_mnoc_cfg, MSM8998_SLAVE_CNOC_MNOC_CFG, 4, -1, 66, true, -1, 0, -1, MSM8998_MASTER_CNOC_MNOC_CFG);
|
||||
DEFINE_QNODE(slv_qm_cfg, MSM8998_SLAVE_QM_CFG, 4, -1, 212, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mss_cfg, MSM8998_SLAVE_MSS_CFG, 4, -1, 48, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_ufs_cfg, MSM8998_SLAVE_UFS_CFG, 4, -1, 92, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tlmm_west, MSM8998_SLAVE_TLMM_WEST, 4, -1, 215, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_a1noc_cfg, MSM8998_SLAVE_A1NOC_CFG, 4, -1, 147, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_ahb2phy, MSM8998_SLAVE_AHB2PHY, 4, -1, 163, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_blsp_2, MSM8998_SLAVE_BLSP_2, 4, -1, 37, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pdm, MSM8998_SLAVE_PDM, 4, -1, 41, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_usb3_0, MSM8998_SLAVE_USB3_0, 4, -1, 22, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_a1noc_smmu_cfg, MSM8998_SLAVE_A1NOC_SMMU_CFG, 8, -1, 149, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_blsp_1, MSM8998_SLAVE_BLSP_1, 4, -1, 39, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_sdcc_2, MSM8998_SLAVE_SDCC_2, 4, -1, 33, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_sdcc_4, MSM8998_SLAVE_SDCC_4, 4, -1, 34, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tsif, MSM8998_SLAVE_TSIF, 4, -1, 35, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_qdss_cfg, MSM8998_SLAVE_QDSS_CFG, 4, -1, 63, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tlmm_east, MSM8998_SLAVE_TLMM_EAST, 4, -1, 213, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_cnoc_mnoc_mmss_cfg, MSM8998_SLAVE_CNOC_MNOC_MMSS_CFG, 8, -1, 58, true, -1, 0, -1, MSM8998_MASTER_CNOC_MNOC_MMSS_CFG);
|
||||
DEFINE_QNODE(slv_srvc_cnoc, MSM8998_SLAVE_SRVC_CNOC, 4, -1, 76, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_crvirt_a2noc, MSM8998_SLAVE_CRVIRT_A2NOC, 8, -1, 207, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_gnoc_bimc, MSM8998_SLAVE_GNOC_BIMC, 32, -1, 210, true, -1, 0, -1, MSM8998_MASTER_GNOC_BIMC);
|
||||
DEFINE_QNODE(slv_camera_cfg, MSM8998_SLAVE_CAMERA_CFG, 8, -1, 3, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_camera_throttle_cfg, MSM8998_SLAVE_CAMERA_THROTTLE_CFG, 8, -1, 154, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_misc_cfg, MSM8998_SLAVE_MISC_CFG, 8, -1, 8, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_venus_throttle_cfg, MSM8998_SLAVE_VENUS_THROTTLE_CFG, 8, -1, 178, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_venus_cfg, MSM8998_SLAVE_VENUS_CFG, 8, -1, 10, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_vmem_cfg, MSM8998_SLAVE_VMEM_CFG, 8, -1, 180, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mmss_clk_xpu_cfg, MSM8998_SLAVE_MMSS_CLK_XPU_CFG, 8, -1, 13, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mmss_clk_cfg, MSM8998_SLAVE_MMSS_CLK_CFG, 8, -1, 12, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_display_cfg, MSM8998_SLAVE_DISPLAY_CFG, 8, -1, 4, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_display_throttle_cfg, MSM8998_SLAVE_DISPLAY_THROTTLE_CFG, 4, -1, 156, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_smmu_cfg, MSM8998_SLAVE_SMMU_CFG, 8, -1, 205, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mnoc_bimc, MSM8998_SLAVE_MNOC_BIMC, 32, -1, 16, true, -1, 0, -1, MSM8998_MASTER_MNOC_BIMC);
|
||||
DEFINE_QNODE(slv_vmem, MSM8998_SLAVE_VMEM, 32, -1, 179, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_srvc_mnoc, MSM8998_SLAVE_SRVC_MNOC, 8, -1, 17, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_hmss, MSM8998_SLAVE_HMSS, 16, -1, 20, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_lpass, MSM8998_SLAVE_LPASS, 16, -1, 21, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_wlan, MSM8998_SLAVE_WLAN, 16, -1, 206, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_snoc_bimc, MSM8998_SLAVE_SNOC_BIMC, 32, -1, 24, false, -1, 0, -1, MSM8998_MASTER_SNOC_BIMC);
|
||||
DEFINE_QNODE(slv_snoc_cnoc, MSM8998_SLAVE_SNOC_CNOC, 16, -1, 25, false, -1, 0, -1, MSM8998_MASTER_SNOC_CNOC);
|
||||
DEFINE_QNODE(slv_imem, MSM8998_SLAVE_IMEM, 16, -1, 26, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pimem, MSM8998_SLAVE_PIMEM, 16, -1, 166, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_qdss_stm, MSM8998_SLAVE_QDSS_STM, 16, -1, 30, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pcie_0, MSM8998_SLAVE_PCIE_0, 16, -1, 84, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_srvc_snoc, MSM8998_SLAVE_SRVC_SNOC, 16, -1, 29, false, -1, 0, -1, 0);
|
||||
|
||||
static struct qcom_icc_node *msm8998_a1noc_nodes[] = {
|
||||
[MASTER_PCIE_0] = &mas_pcie_0,
|
||||
[MASTER_USB3] = &mas_usb3,
|
||||
[MASTER_UFS] = &mas_ufs,
|
||||
[MASTER_BLSP_2] = &mas_blsp_2,
|
||||
[SLAVE_A1NOC_SNOC] = &slv_a1noc_snoc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_a1noc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x60000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_a1noc = {
|
||||
.nodes = msm8998_a1noc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_a1noc_nodes),
|
||||
.regmap_cfg = &msm8998_a1noc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_a2noc_nodes[] = {
|
||||
[MASTER_IPA] = &mas_ipa,
|
||||
[MASTER_CNOC_A2NOC] = &mas_cnoc_a2noc,
|
||||
[MASTER_SDCC_2] = &mas_sdcc_2,
|
||||
[MASTER_SDCC_4] = &mas_sdcc_4,
|
||||
[MASTER_TSIF] = &mas_tsif,
|
||||
[MASTER_BLSP_1] = &mas_blsp_1,
|
||||
[MASTER_CRVIRT_A2NOC] = &mas_crvirt_a2noc,
|
||||
[MASTER_CRYPTO_C0] = &mas_crypto,
|
||||
[SLAVE_A2NOC_SNOC] = &slv_a2noc_snoc,
|
||||
[SLAVE_CRVIRT_A2NOC] = &slv_crvirt_a2noc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_a2noc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x60000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_a2noc = {
|
||||
.nodes = msm8998_a2noc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_a2noc_nodes),
|
||||
.regmap_cfg = &msm8998_a2noc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_bimc_nodes[] = {
|
||||
[MASTER_GNOC_BIMC] = &mas_gnoc_bimc,
|
||||
[MASTER_OXILI] = &mas_oxili,
|
||||
[MASTER_MNOC_BIMC] = &mas_mnoc_bimc,
|
||||
[MASTER_SNOC_BIMC] = &mas_snoc_bimc,
|
||||
[SLAVE_EBI] = &slv_ebi,
|
||||
[SLAVE_HMSS_L3] = &slv_hmss_l3,
|
||||
[SLAVE_BIMC_SNOC_0] = &slv_bimc_snoc_0,
|
||||
[SLAVE_BIMC_SNOC_1] = &slv_bimc_snoc_1,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_bimc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x80000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_bimc = {
|
||||
.nodes = msm8998_bimc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_bimc_nodes),
|
||||
.regmap_cfg = &msm8998_bimc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_cnoc_nodes[] = {
|
||||
[MASTER_SNOC_CNOC] = &mas_snoc_cnoc,
|
||||
[MASTER_QDSS_DAP] = &mas_qdss_dap,
|
||||
[SLAVE_CNOC_A2NOC] = &slv_cnoc_a2noc,
|
||||
[SLAVE_SSC_CFG] = &slv_ssc_cfg,
|
||||
[SLAVE_MPM] = &slv_mpm,
|
||||
[SLAVE_PMIC_ARB] = &slv_pmic_arb,
|
||||
[SLAVE_TLMM_NORTH] = &slv_tlmm_north,
|
||||
[SLAVE_PIMEM_CFG] = &slv_pimem_cfg,
|
||||
[SLAVE_IMEM_CFG] = &slv_imem_cfg,
|
||||
[SLAVE_MESSAGE_RAM] = &slv_message_ram,
|
||||
[SLAVE_SKL] = &slv_skl,
|
||||
[SLAVE_BIMC_CFG] = &slv_bimc_cfg,
|
||||
[SLAVE_PRNG] = &slv_prng,
|
||||
[SLAVE_A2NOC_CFG] = &slv_a2noc_cfg,
|
||||
[SLAVE_IPA] = &slv_ipa,
|
||||
[SLAVE_TCSR] = &slv_tcsr,
|
||||
[SLAVE_SNOC_CFG] = &slv_snoc_cfg,
|
||||
[SLAVE_CLK_CTL] = &slv_clk_ctl,
|
||||
[SLAVE_GLM] = &slv_glm,
|
||||
[SLAVE_SPDM] = &slv_spdm,
|
||||
[SLAVE_GPUSS_CFG] = &slv_gpuss_cfg,
|
||||
[SLAVE_CNOC_MNOC_CFG] = &slv_cnoc_mnoc_cfg,
|
||||
[SLAVE_QM_CFG] = &slv_qm_cfg,
|
||||
[SLAVE_MSS_CFG] = &slv_mss_cfg,
|
||||
[SLAVE_UFS_CFG] = &slv_ufs_cfg,
|
||||
[SLAVE_TLMM_WEST] = &slv_tlmm_west,
|
||||
[SLAVE_A1NOC_CFG] = &slv_a1noc_cfg,
|
||||
[SLAVE_AHB2PHY] = &slv_ahb2phy,
|
||||
[SLAVE_BLSP_2] = &slv_blsp_2,
|
||||
[SLAVE_PDM] = &slv_pdm,
|
||||
[SLAVE_USB3_0] = &slv_usb3_0,
|
||||
[SLAVE_A1NOC_SMMU_CFG] = &slv_a1noc_smmu_cfg,
|
||||
[SLAVE_BLSP_1] = &slv_blsp_1,
|
||||
[SLAVE_SDCC_2] = &slv_sdcc_2,
|
||||
[SLAVE_SDCC_4] = &slv_sdcc_4,
|
||||
[SLAVE_TSIF] = &slv_tsif,
|
||||
[SLAVE_QDSS_CFG] = &slv_qdss_cfg,
|
||||
[SLAVE_TLMM_EAST] = &slv_tlmm_east,
|
||||
[SLAVE_CNOC_MNOC_MMSS_CFG] = &slv_cnoc_mnoc_mmss_cfg,
|
||||
[SLAVE_SRVC_CNOC] = &slv_srvc_cnoc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_cnoc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x10000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_cnoc = {
|
||||
.nodes = msm8998_cnoc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_cnoc_nodes),
|
||||
.regmap_cfg = &msm8998_cnoc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_gnoc_nodes[] = {
|
||||
[MASTER_APSS_PROC] = &mas_apss_proc,
|
||||
[SLAVE_GNOC_BIMC] = &slv_gnoc_bimc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_gnoc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x10000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_gnoc = {
|
||||
.nodes = msm8998_gnoc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_gnoc_nodes),
|
||||
.regmap_cfg = &msm8998_gnoc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_mnoc_nodes[] = {
|
||||
[MASTER_CNOC_MNOC_CFG] = &mas_cnoc_mnoc_cfg,
|
||||
[MASTER_CPP] = &mas_cpp,
|
||||
[MASTER_JPEG] = &mas_jpeg,
|
||||
[MASTER_MDP_P0] = &mas_mdp_p0,
|
||||
[MASTER_MDP_P1] = &mas_mdp_p1,
|
||||
[MASTER_ROTATOR] = &mas_rotator,
|
||||
[MASTER_VENUS] = &mas_venus,
|
||||
[MASTER_VFE] = &mas_vfe,
|
||||
[MASTER_VENUS_VMEM] = &mas_venus_vmem,
|
||||
[SLAVE_MNOC_BIMC] = &slv_mnoc_bimc,
|
||||
[SLAVE_VMEM] = &slv_vmem,
|
||||
[SLAVE_SRVC_MNOC] = &slv_srvc_mnoc,
|
||||
[MASTER_CNOC_MNOC_MMSS_CFG] = &mas_cnoc_mnoc_mmss_cfg,
|
||||
[SLAVE_CAMERA_CFG] = &slv_camera_cfg,
|
||||
[SLAVE_CAMERA_THROTTLE_CFG] = &slv_camera_throttle_cfg,
|
||||
[SLAVE_MISC_CFG] = &slv_misc_cfg,
|
||||
[SLAVE_VENUS_THROTTLE_CFG] = &slv_venus_throttle_cfg,
|
||||
[SLAVE_VENUS_CFG] = &slv_venus_cfg,
|
||||
[SLAVE_VMEM_CFG] = &slv_vmem_cfg,
|
||||
[SLAVE_MMSS_CLK_XPU_CFG] = &slv_mmss_clk_xpu_cfg,
|
||||
[SLAVE_MMSS_CLK_CFG] = &slv_mmss_clk_cfg,
|
||||
[SLAVE_DISPLAY_CFG] = &slv_display_cfg,
|
||||
[SLAVE_DISPLAY_THROTTLE_CFG] = &slv_display_throttle_cfg,
|
||||
[SLAVE_SMMU_CFG] = &slv_smmu_cfg,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_mnoc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x10000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_mnoc = {
|
||||
.nodes = msm8998_mnoc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_mnoc_nodes),
|
||||
.regmap_cfg = &msm8998_mnoc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_snoc_nodes[] = {
|
||||
[MASTER_HMSS] = &mas_hmss,
|
||||
[MASTER_QDSS_BAM] = &mas_qdss_bam,
|
||||
[MASTER_SNOC_CFG] = &mas_snoc_cfg,
|
||||
[MASTER_BIMC_SNOC_0] = &mas_bimc_snoc_0,
|
||||
[MASTER_BIMC_SNOC_1] = &mas_bimc_snoc_1,
|
||||
[MASTER_A1NOC_SNOC] = &mas_a1noc_snoc,
|
||||
[MASTER_A2NOC_SNOC] = &mas_a2noc_snoc,
|
||||
[MASTER_QDSS_ETR] = &mas_qdss_etr,
|
||||
[SLAVE_HMSS] = &slv_hmss,
|
||||
[SLAVE_LPASS] = &slv_lpass,
|
||||
[SLAVE_WLAN] = &slv_wlan,
|
||||
[SLAVE_SNOC_BIMC] = &slv_snoc_bimc,
|
||||
[SLAVE_SNOC_CNOC] = &slv_snoc_cnoc,
|
||||
[SLAVE_IMEM] = &slv_imem,
|
||||
[SLAVE_PIMEM] = &slv_pimem,
|
||||
[SLAVE_QDSS_STM] = &slv_qdss_stm,
|
||||
[SLAVE_PCIE_0] = &slv_pcie_0,
|
||||
[SLAVE_SRVC_SNOC] = &slv_srvc_snoc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_snoc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x40000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_snoc = {
|
||||
.nodes = msm8998_snoc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_snoc_nodes),
|
||||
.regmap_cfg = &msm8998_snoc_regmap_config,
|
||||
};
|
||||
|
||||
static int qcom_icc_bimc_set_qos_health(struct regmap *rmap,
|
||||
struct qcom_icc_qos *qos,
|
||||
int regnum)
|
||||
{
|
||||
u32 val;
|
||||
u32 mask;
|
||||
|
||||
val = qos->prio_level;
|
||||
mask = M_BKE_HEALTH_CFG_PRIOLVL_MASK;
|
||||
|
||||
val |= qos->areq_prio << M_BKE_HEALTH_CFG_AREQPRIO_SHIFT;
|
||||
mask |= M_BKE_HEALTH_CFG_AREQPRIO_MASK;
|
||||
|
||||
/* LIMITCMDS is not present on M_BKE_HEALTH_3 */
|
||||
if (regnum != 3) {
|
||||
val |= qos->limit_commands << M_BKE_HEALTH_CFG_LIMITCMDS_SHIFT;
|
||||
mask |= M_BKE_HEALTH_CFG_LIMITCMDS_MASK;
|
||||
}
|
||||
|
||||
return regmap_update_bits(rmap,
|
||||
M_BKE_HEALTH_CFG_ADDR(regnum, qos->qos_port),
|
||||
mask, val);
|
||||
}
|
||||
|
||||
static int qcom_icc_set_bimc_qos(struct icc_node *src, u64 max_bw,
|
||||
bool bypass_mode)
|
||||
{
|
||||
struct qcom_icc_provider *qp;
|
||||
struct qcom_icc_node *qn;
|
||||
struct icc_provider *provider;
|
||||
u32 mode = NOC_QOS_MODE_BYPASS;
|
||||
u32 val = 0;
|
||||
int i, rc = 0;
|
||||
|
||||
qn = src->data;
|
||||
provider = src->provider;
|
||||
qp = to_qcom_provider(provider);
|
||||
|
||||
if (qn->qos.qos_mode != -1)
|
||||
mode = qn->qos.qos_mode;
|
||||
|
||||
/*
|
||||
* QoS Priority: The QoS Health parameters are getting considered
|
||||
* only if we are NOT in Bypass Mode.
|
||||
*/
|
||||
if (mode != NOC_QOS_MODE_BYPASS) {
|
||||
for (i = 3; i >= 0; i--) {
|
||||
rc = qcom_icc_bimc_set_qos_health(qp->regmap,
|
||||
&qn->qos, i);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Set BKE_EN to 1 when Fixed, Regulator or Limiter Mode */
|
||||
val = 1;
|
||||
}
|
||||
|
||||
return regmap_update_bits(qp->regmap, M_BKE_EN_ADDR(qn->qos.qos_port),
|
||||
M_BKE_EN_EN_BMASK, val);
|
||||
}
|
||||
|
||||
static int qcom_icc_noc_set_qos_priority(struct regmap *rmap,
|
||||
struct qcom_icc_qos *qos)
|
||||
{
|
||||
u32 val;
|
||||
int rc;
|
||||
|
||||
/* Must be updated one at a time, P1 first, P0 last */
|
||||
val = qos->areq_prio << NOC_QOS_PRIORITY_P1_SHIFT;
|
||||
rc = regmap_update_bits(rmap, NOC_QOS_PRIORITYn_ADDR(qos->qos_port),
|
||||
NOC_QOS_PRIORITY_MASK, val);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
val = qos->prio_level << NOC_QOS_PRIORITY_P0_SHIFT;
|
||||
return regmap_update_bits(rmap, NOC_QOS_PRIORITYn_ADDR(qos->qos_port),
|
||||
NOC_QOS_PRIORITY_MASK, val);
|
||||
}
|
||||
|
||||
static int qcom_icc_set_noc_qos(struct icc_node *src, u64 max_bw)
|
||||
{
|
||||
struct qcom_icc_provider *qp;
|
||||
struct qcom_icc_node *qn;
|
||||
struct icc_provider *provider;
|
||||
u32 mode = NOC_QOS_MODE_BYPASS;
|
||||
int rc = 0;
|
||||
|
||||
qn = src->data;
|
||||
provider = src->provider;
|
||||
qp = to_qcom_provider(provider);
|
||||
|
||||
if (qn->qos.qos_port < 0) {
|
||||
dev_dbg(src->provider->dev,
|
||||
"NoC QoS: Skipping %s: vote aggregated on parent.\n",
|
||||
qn->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (qn->qos.qos_mode != -1)
|
||||
mode = qn->qos.qos_mode;
|
||||
|
||||
if (mode == NOC_QOS_MODE_FIXED) {
|
||||
dev_dbg(src->provider->dev, "NoC QoS: %s: Set Fixed mode\n",
|
||||
qn->name);
|
||||
rc = qcom_icc_noc_set_qos_priority(qp->regmap, &qn->qos);
|
||||
if (rc)
|
||||
return rc;
|
||||
} else if (mode == NOC_QOS_MODE_BYPASS) {
|
||||
dev_dbg(src->provider->dev, "NoC QoS: %s: Set Bypass mode\n",
|
||||
qn->name);
|
||||
}
|
||||
|
||||
return regmap_update_bits(qp->regmap,
|
||||
NOC_QOS_MODEn_ADDR(qn->qos.qos_port),
|
||||
NOC_QOS_MODEn_MASK, mode);
|
||||
}
|
||||
|
||||
static int qcom_icc_qos_set(struct icc_node *node, u64 sum_bw)
|
||||
{
|
||||
struct qcom_icc_provider *qp = to_qcom_provider(node->provider);
|
||||
struct qcom_icc_node *qn = node->data;
|
||||
|
||||
dev_dbg(node->provider->dev, "Setting QoS for %s\n", qn->name);
|
||||
|
||||
if (qp->is_bimc_node)
|
||||
return qcom_icc_set_bimc_qos(node, sum_bw,
|
||||
(qn->qos.qos_mode == NOC_QOS_MODE_BYPASS));
|
||||
|
||||
return qcom_icc_set_noc_qos(node, sum_bw);
|
||||
}
|
||||
|
||||
static int qcom_icc_rpm_set(int mas_rpm_id, int slv_rpm_id, u64 sum_bw)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (mas_rpm_id != -1) {
|
||||
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
|
||||
RPM_BUS_MASTER_REQ,
|
||||
mas_rpm_id,
|
||||
sum_bw);
|
||||
if (ret) {
|
||||
pr_err("qcom_icc_rpm_smd_send mas %d error %d\n",
|
||||
mas_rpm_id, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (slv_rpm_id != -1) {
|
||||
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
|
||||
RPM_BUS_SLAVE_REQ,
|
||||
slv_rpm_id,
|
||||
sum_bw);
|
||||
if (ret) {
|
||||
pr_err("qcom_icc_rpm_smd_send slv %d error %d\n",
|
||||
slv_rpm_id, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
|
||||
{
|
||||
struct qcom_icc_provider *qp;
|
||||
struct qcom_icc_node *qn;
|
||||
struct icc_provider *provider;
|
||||
struct icc_node *n;
|
||||
u64 sum_bw;
|
||||
u64 max_peak_bw;
|
||||
u64 rate;
|
||||
u32 agg_avg = 0;
|
||||
u32 agg_peak = 0;
|
||||
int ret, i;
|
||||
|
||||
qn = src->data;
|
||||
provider = src->provider;
|
||||
qp = to_qcom_provider(provider);
|
||||
|
||||
list_for_each_entry(n, &provider->nodes, node_list)
|
||||
provider->aggregate(n, 0, n->avg_bw, n->peak_bw,
|
||||
&agg_avg, &agg_peak);
|
||||
|
||||
sum_bw = icc_units_to_bps(agg_avg);
|
||||
max_peak_bw = icc_units_to_bps(agg_peak);
|
||||
|
||||
if (!qn->qos.ap_owned) {
|
||||
/* send bandwidth request message to the RPM processor */
|
||||
ret = qcom_icc_rpm_set(qn->mas_rpm_id, qn->slv_rpm_id, sum_bw);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (qn->qos.qos_mode != -1) {
|
||||
/* set bandwidth directly from the AP */
|
||||
ret = qcom_icc_qos_set(src, sum_bw);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
rate = max(sum_bw, max_peak_bw);
|
||||
|
||||
do_div(rate, qn->buswidth);
|
||||
|
||||
if (qn->rate == rate)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < qp->num_clks; i++) {
|
||||
ret = clk_set_rate(qp->bus_clks[i].clk, rate);
|
||||
if (ret) {
|
||||
pr_err("%s clk_set_rate error: %d\n",
|
||||
qp->bus_clks[i].id, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
qn->rate = rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qnoc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct qcom_icc_desc *desc;
|
||||
struct icc_onecell_data *data;
|
||||
struct icc_provider *provider;
|
||||
struct qcom_icc_node **qnodes;
|
||||
struct qcom_icc_provider *qp;
|
||||
struct icc_node *node;
|
||||
struct resource *res;
|
||||
size_t num_nodes, i;
|
||||
int ret;
|
||||
|
||||
/* wait for the RPM proxy */
|
||||
if (!qcom_icc_rpm_smd_available())
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
desc = of_device_get_match_data(dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
qnodes = desc->nodes;
|
||||
num_nodes = desc->num_nodes;
|
||||
|
||||
qp = devm_kzalloc(dev, sizeof(*qp), GFP_KERNEL);
|
||||
if (!qp)
|
||||
return -ENOMEM;
|
||||
|
||||
data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm8998-mnoc")) {
|
||||
qp->bus_clks = devm_kmemdup(dev, bus_mm_clocks,
|
||||
sizeof(bus_mm_clocks), GFP_KERNEL);
|
||||
qp->num_clks = ARRAY_SIZE(bus_mm_clocks);
|
||||
} else {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm8998-bimc"))
|
||||
qp->is_bimc_node = true;
|
||||
|
||||
qp->bus_clks = devm_kmemdup(dev, bus_clocks, sizeof(bus_clocks),
|
||||
GFP_KERNEL);
|
||||
qp->num_clks = ARRAY_SIZE(bus_clocks);
|
||||
}
|
||||
if (!qp->bus_clks)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
qp->mmio = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(qp->mmio)) {
|
||||
dev_err(dev, "Cannot ioremap interconnect bus resource\n");
|
||||
return PTR_ERR(qp->mmio);
|
||||
}
|
||||
|
||||
qp->regmap = devm_regmap_init_mmio(dev, qp->mmio, desc->regmap_cfg);
|
||||
if (IS_ERR(qp->regmap)) {
|
||||
dev_err(dev, "Cannot regmap interconnect bus resource\n");
|
||||
return PTR_ERR(qp->regmap);
|
||||
}
|
||||
|
||||
ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_bulk_prepare_enable(qp->num_clks, qp->bus_clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
provider = &qp->provider;
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
provider->dev = dev;
|
||||
provider->set = qcom_icc_set;
|
||||
provider->aggregate = icc_std_aggregate;
|
||||
provider->xlate = of_icc_xlate_onecell;
|
||||
provider->data = data;
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret) {
|
||||
dev_err(dev, "error adding interconnect provider: %d\n", ret);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_nodes; i++) {
|
||||
size_t j;
|
||||
|
||||
node = icc_node_create(qnodes[i]->id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err;
|
||||
}
|
||||
|
||||
node->name = qnodes[i]->name;
|
||||
node->data = qnodes[i];
|
||||
icc_node_add(node, provider);
|
||||
|
||||
for (j = 0; j < qnodes[i]->num_links; j++)
|
||||
icc_link_create(node, qnodes[i]->links[j]);
|
||||
|
||||
data->nodes[i] = node;
|
||||
}
|
||||
data->num_nodes = num_nodes;
|
||||
platform_set_drvdata(pdev, qp);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
icc_nodes_remove(provider);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
icc_provider_del(provider);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qnoc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
|
||||
icc_nodes_remove(&qp->provider);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
icc_provider_del(&qp->provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id msm8998_noc_of_match[] = {
|
||||
{ .compatible = "qcom,msm8998-a1noc", .data = &msm8998_a1noc },
|
||||
{ .compatible = "qcom,msm8998-a2noc", .data = &msm8998_a2noc },
|
||||
{ .compatible = "qcom,msm8998-bimc", .data = &msm8998_bimc },
|
||||
{ .compatible = "qcom,msm8998-cnoc", .data = &msm8998_cnoc },
|
||||
{ .compatible = "qcom,msm8998-gnoc", .data = &msm8998_gnoc },
|
||||
{ .compatible = "qcom,msm8998-mnoc", .data = &msm8998_mnoc },
|
||||
{ .compatible = "qcom,msm8998-snoc", .data = &msm8998_snoc },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, msm8998_noc_of_match);
|
||||
|
||||
static struct platform_driver msm8998_noc_driver = {
|
||||
.probe = qnoc_probe,
|
||||
.remove = qnoc_remove,
|
||||
.driver = {
|
||||
.name = "qnoc-msm8998",
|
||||
.of_match_table = msm8998_noc_of_match,
|
||||
.sync_state = icc_sync_state,
|
||||
},
|
||||
};
|
||||
module_platform_driver(msm8998_noc_driver);
|
||||
MODULE_DESCRIPTION("Qualcomm msm8998 NoC driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
@ -197,11 +197,13 @@ static int qcom_adreno_smmu_alloc_context_bank(struct arm_smmu_domain *smmu_doma
|
|||
|
||||
static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
|
||||
{
|
||||
/*
|
||||
const struct device_node *np = smmu->dev->of_node;
|
||||
|
||||
if (of_device_is_compatible(np, "qcom,msm8996-smmu-v2"))
|
||||
if (of_device_is_compatible(np, "qcom,msm8996-smmu-v2") ||
|
||||
of_device_is_compatible(np, "qcom,msm8998-smmu-v2") ||
|
||||
of_device_is_compatible(np, "qcom,sdm630-smmu-v2"))
|
||||
return false;
|
||||
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -245,12 +247,14 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
|
|||
{ .compatible = "qcom,adreno" },
|
||||
{ .compatible = "qcom,mdp4" },
|
||||
{ .compatible = "qcom,mdss" },
|
||||
{ .compatible = "qcom,msm8998-mss-pil" },
|
||||
{ .compatible = "qcom,sc7180-mdss" },
|
||||
{ .compatible = "qcom,sc7180-mss-pil" },
|
||||
{ .compatible = "qcom,sc7280-mdss" },
|
||||
{ .compatible = "qcom,sc7280-mss-pil" },
|
||||
{ .compatible = "qcom,sc8180x-mdss" },
|
||||
{ .compatible = "qcom,sm8250-mdss" },
|
||||
{ .compatible = "qcom,sdm660-mss-pil" },
|
||||
{ .compatible = "qcom,sdm845-mdss" },
|
||||
{ .compatible = "qcom,sdm845-mss-pil" },
|
||||
{ }
|
||||
|
|
@ -285,7 +289,8 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
|
|||
reg = arm_smmu_gr0_read(smmu, last_s2cr);
|
||||
if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
|
||||
qsmmu->bypass_quirk = true;
|
||||
qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
|
||||
if (qsmmu->bypass_cbndx == 0xff)
|
||||
qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
|
||||
|
||||
set_bit(qsmmu->bypass_cbndx, smmu->context_map);
|
||||
|
||||
|
|
@ -377,8 +382,15 @@ static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
|
|||
static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
|
||||
{
|
||||
const struct device_node *np = smmu->dev->of_node;
|
||||
struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
|
||||
|
||||
arm_mmu500_reset(smmu);
|
||||
/*
|
||||
* Execute the mmu-500 reset implementation detail only if there
|
||||
* are no secured untouchable contexts in this iommu, otherwise
|
||||
* the system will crash.
|
||||
*/
|
||||
if (bitmap_empty(qsmmu->reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS))
|
||||
arm_mmu500_reset(smmu);
|
||||
|
||||
if (of_device_is_compatible(np, "qcom,sdm845-smmu-500"))
|
||||
return qcom_sdm845_smmu500_reset(smmu);
|
||||
|
|
@ -386,11 +398,20 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool qcom_smmu500_reset_cb_nodisable(struct arm_smmu_device *smmu,
|
||||
int cbndx)
|
||||
{
|
||||
struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
|
||||
|
||||
return test_bit(cbndx, qsmmu->reset_cb_nodisable_mask);
|
||||
}
|
||||
|
||||
static const struct arm_smmu_impl qcom_smmu_impl = {
|
||||
.init_context = qcom_smmu_init_context,
|
||||
.cfg_probe = qcom_smmu_cfg_probe,
|
||||
.def_domain_type = qcom_smmu_def_domain_type,
|
||||
.reset = qcom_smmu500_reset,
|
||||
.reset_cb_nodisable = qcom_smmu500_reset_cb_nodisable,
|
||||
.write_s2cr = qcom_smmu_write_s2cr,
|
||||
.tlb_sync = qcom_smmu_tlb_sync,
|
||||
};
|
||||
|
|
@ -399,6 +420,7 @@ static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
|
|||
.init_context = qcom_adreno_smmu_init_context,
|
||||
.def_domain_type = qcom_smmu_def_domain_type,
|
||||
.reset = qcom_smmu500_reset,
|
||||
.reset_cb_nodisable = qcom_smmu500_reset_cb_nodisable,
|
||||
.alloc_context_bank = qcom_adreno_smmu_alloc_context_bank,
|
||||
.write_sctlr = qcom_adreno_smmu_write_sctlr,
|
||||
.tlb_sync = qcom_smmu_tlb_sync,
|
||||
|
|
@ -407,7 +429,10 @@ static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
|
|||
static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
|
||||
const struct arm_smmu_impl *impl)
|
||||
{
|
||||
const struct device_node *np = smmu->dev->of_node;
|
||||
struct qcom_smmu *qsmmu;
|
||||
u8 reset_nodisable_cbs[ARM_SMMU_MAX_CBS];
|
||||
int i, sz;
|
||||
|
||||
/* Check to make sure qcom_scm has finished probing */
|
||||
if (!qcom_scm_is_available())
|
||||
|
|
@ -419,6 +444,34 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
|
|||
|
||||
qsmmu->smmu.impl = impl;
|
||||
qsmmu->cfg = qcom_smmu_impl_data(smmu);
|
||||
qsmmu->bypass_cbndx = 0xff;
|
||||
bitmap_zero(qsmmu->reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS);
|
||||
|
||||
if (np != NULL) {
|
||||
/*
|
||||
* This property is optional and we expect to fail finding it if:
|
||||
* - Using the default bypass_cbndx (in the .cfg_probe cb) is fine; or
|
||||
* - We are booting on ACPI
|
||||
*/
|
||||
of_property_read_u8(np, "qcom,bypass-cbndx", &qsmmu->bypass_cbndx);
|
||||
|
||||
/*
|
||||
* Some context banks may not be disabled because they are
|
||||
* secured: read from DT a list of secured contexts that cannot
|
||||
* be disabled without crashing the system.
|
||||
* This list is optional, as not all firmware configurations do
|
||||
* require us skipping disablement of context banks.
|
||||
*/
|
||||
sz = of_property_read_variable_u8_array(np, "qcom,reset-nodisable-cbs",
|
||||
reset_nodisable_cbs,
|
||||
1, ARM_SMMU_MAX_CBS);
|
||||
if (sz > 0) {
|
||||
for (i = 0; i < sz; i++) {
|
||||
__set_bit(reset_nodisable_cbs[i],
|
||||
qsmmu->reset_cb_nodisable_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &qsmmu->smmu;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
struct qcom_smmu {
|
||||
struct arm_smmu_device smmu;
|
||||
const struct qcom_smmu_config *cfg;
|
||||
DECLARE_BITMAP(reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS);
|
||||
bool bypass_quirk;
|
||||
u8 bypass_cbndx;
|
||||
u32 stall_enabled;
|
||||
|
|
|
|||
|
|
@ -1600,6 +1600,16 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
|
|||
|
||||
/* Make sure all context banks are disabled and clear CB_FSR */
|
||||
for (i = 0; i < smmu->num_context_banks; ++i) {
|
||||
/*
|
||||
* Some context banks cannot be disabled due to hypervisor
|
||||
* configuration on some systems; if this is the case,
|
||||
* skip disabling and writing FAULT on the CB FSR in order
|
||||
* to avoid a system crash.
|
||||
*/
|
||||
if (smmu->impl && smmu->impl->reset_cb_nodisable &&
|
||||
smmu->impl->reset_cb_nodisable(smmu, i)) {
|
||||
continue;
|
||||
}
|
||||
arm_smmu_write_context_bank(smmu, i);
|
||||
arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -430,6 +430,7 @@ struct arm_smmu_impl {
|
|||
u64 val);
|
||||
int (*cfg_probe)(struct arm_smmu_device *smmu);
|
||||
int (*reset)(struct arm_smmu_device *smmu);
|
||||
bool (*reset_cb_nodisable)(struct arm_smmu_device *smmu, int cbndx);
|
||||
int (*init_context)(struct arm_smmu_domain *smmu_domain,
|
||||
struct io_pgtable_cfg *cfg, struct device *dev);
|
||||
void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
|
||||
|
|
|
|||
|
|
@ -126,7 +126,8 @@ static int pattern_trig_start_pattern(struct led_classdev *led_cdev)
|
|||
|
||||
if (data->is_hw_pattern) {
|
||||
return led_cdev->pattern_set(led_cdev, data->patterns,
|
||||
data->npatterns, data->repeat);
|
||||
data->npatterns,
|
||||
data->last_repeat);
|
||||
}
|
||||
|
||||
/* At least 2 tuples for software pattern. */
|
||||
|
|
|
|||
|
|
@ -2099,6 +2099,18 @@ config MFD_WCD934X
|
|||
This driver provides common support WCD934x audio codec and its
|
||||
associated Pin Controller, Soundwire Controller and Audio codec.
|
||||
|
||||
config MFD_WCD9335
|
||||
tristate "Support for WCD9335 Codec"
|
||||
depends on SLIMBUS
|
||||
select REGMAP
|
||||
select REGMAP_SLIMBUS
|
||||
select REGMAP_IRQ
|
||||
select MFD_CORE
|
||||
help
|
||||
Support for the Qualcomm WCD9335 Codec.
|
||||
This driver provides common support WCD9335 audio codec and its
|
||||
associated Pin Controller, Soundwire Controller and Audio codec.
|
||||
|
||||
config MFD_ATC260X
|
||||
tristate
|
||||
select MFD_CORE
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ ifeq ($(CONFIG_MFD_CS47L24),y)
|
|||
arizona-objs += cs47l24-tables.o
|
||||
endif
|
||||
obj-$(CONFIG_MFD_WCD934X) += wcd934x.o
|
||||
obj-$(CONFIG_MFD_WCD9335) += wcd9335.o
|
||||
obj-$(CONFIG_MFD_WM8400) += wm8400-core.o
|
||||
wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o
|
||||
wm831x-objs += wm831x-auxadc.o
|
||||
|
|
|
|||
300
drivers/mfd/wcd9335.c
Normal file
300
drivers/mfd/wcd9335.c
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2019, Linaro Limited
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/wcd9335/registers.h>
|
||||
#include <linux/mfd/wcd9335/wcd9335.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slimbus.h>
|
||||
|
||||
#define WCD9335_REGMAP_IRQ_REG(_irq, _off, _mask) \
|
||||
[_irq] = { \
|
||||
.reg_offset = (_off), \
|
||||
.mask = (_mask), \
|
||||
.type = { \
|
||||
.type_reg_offset = (_off), \
|
||||
.types_supported = IRQ_TYPE_EDGE_BOTH, \
|
||||
.type_reg_mask = (_mask), \
|
||||
.type_level_low_val = (_mask), \
|
||||
.type_level_high_val = (_mask), \
|
||||
.type_falling_val = 0, \
|
||||
.type_rising_val = 0, \
|
||||
}, \
|
||||
}
|
||||
|
||||
static const struct mfd_cell wcd9335_devices[] = {
|
||||
{
|
||||
.name = "wcd9335-codec",
|
||||
}, {
|
||||
.name = "wcd9335-gpio",
|
||||
.of_compatible = "qcom,wcd9340-gpio",
|
||||
}, {
|
||||
.name = "wcd9335-soundwire",
|
||||
.of_compatible = "qcom,soundwire-v1.3.0",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_irq wcd9335_irqs[] = {
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_SLIMBUS, 0, BIT(0)),
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_HPH_PA_OCPL_FAULT, 0, BIT(2)),
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_HPH_PA_OCPR_FAULT, 0, BIT(3)),
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_SW_DET, 1, BIT(0)),
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, 1, BIT(1)),
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, 1, BIT(2)),
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, 1, BIT(3)),
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 1, BIT(4)),
|
||||
WCD9335_REGMAP_IRQ_REG(WCD9335_IRQ_SOUNDWIRE, 2, BIT(4)),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip wcd9335_regmap_irq_chip = {
|
||||
.name = "wcd9335_irq",
|
||||
.status_base = WCD9335_INTR_PIN1_STATUS0,
|
||||
.mask_base = WCD9335_INTR_PIN1_MASK0,
|
||||
.ack_base = WCD9335_INTR_PIN1_CLEAR0,
|
||||
.type_base = WCD9335_INTR_LEVEL0,
|
||||
.num_type_reg = 4,
|
||||
.type_in_mask = false,
|
||||
.num_regs = 4,
|
||||
.irqs = wcd9335_irqs,
|
||||
.num_irqs = ARRAY_SIZE(wcd9335_irqs),
|
||||
};
|
||||
|
||||
static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case WCD9335_INTR_PIN1_STATUS0...WCD9335_INTR_PIN2_CLEAR3:
|
||||
case WCD9335_SWR_AHB_BRIDGE_RD_DATA_0:
|
||||
case WCD9335_SWR_AHB_BRIDGE_RD_DATA_1:
|
||||
case WCD9335_SWR_AHB_BRIDGE_RD_DATA_2:
|
||||
case WCD9335_SWR_AHB_BRIDGE_RD_DATA_3:
|
||||
case WCD9335_SWR_AHB_BRIDGE_ACCESS_STATUS:
|
||||
case WCD9335_ANA_MBHC_RESULT_3:
|
||||
case WCD9335_ANA_MBHC_RESULT_2:
|
||||
case WCD9335_ANA_MBHC_RESULT_1:
|
||||
case WCD9335_ANA_MBHC_MECH:
|
||||
case WCD9335_ANA_MBHC_ELECT:
|
||||
case WCD9335_ANA_MBHC_ZDET:
|
||||
case WCD9335_ANA_MICB2:
|
||||
case WCD9335_ANA_RCO:
|
||||
case WCD9335_ANA_BIAS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static const struct regmap_range_cfg wcd9335_ranges[] = {
|
||||
{ .name = "WCD9335",
|
||||
.range_min = 0x0,
|
||||
.range_max = WCD9335_MAX_REGISTER,
|
||||
.selector_reg = WCD9335_SEL_REGISTER,
|
||||
.selector_mask = WCD9335_SEL_MASK,
|
||||
.selector_shift = WCD9335_SEL_SHIFT,
|
||||
.window_start = WCD9335_WINDOW_START,
|
||||
.window_len = WCD9335_WINDOW_LENGTH,
|
||||
},
|
||||
};
|
||||
|
||||
static struct regmap_config wcd9335_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.max_register = 0xffff,
|
||||
.can_multi_write = true,
|
||||
.ranges = wcd9335_ranges,
|
||||
.num_ranges = ARRAY_SIZE(wcd9335_ranges),
|
||||
.volatile_reg = wcd9335_is_volatile_register,
|
||||
};
|
||||
|
||||
static int wcd9335_bring_up(struct wcd9335_ddata *ddata)
|
||||
{
|
||||
struct regmap *regmap = ddata->regmap;
|
||||
u16 id_minor, id_major;
|
||||
int ret;
|
||||
|
||||
ret = regmap_bulk_read(regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
|
||||
(u8 *)&id_minor, sizeof(u16));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_bulk_read(regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2,
|
||||
(u8 *)&id_major, sizeof(u16));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(ddata->dev, "WCD934x chip id major 0x%x, minor 0x%x\n",
|
||||
id_major, id_minor);
|
||||
|
||||
regmap_write(regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
|
||||
regmap_write(regmap, WCD9335_SIDO_NEW_VOUT_A_STARTUP, 0x19);
|
||||
regmap_write(regmap, WCD9335_SIDO_NEW_VOUT_D_STARTUP, 0x15);
|
||||
/* Add 1msec delay for VOUT to settle */
|
||||
usleep_range(1000, 1100);
|
||||
regmap_write(regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
|
||||
regmap_write(regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
|
||||
regmap_write(regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
|
||||
regmap_write(regmap, WCD9335_CODEC_RPM_RST_CTL, 0x7);
|
||||
regmap_write(regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd9335_slim_status_up(struct slim_device *sdev)
|
||||
{
|
||||
struct device *dev = &sdev->dev;
|
||||
struct wcd9335_ddata *ddata;
|
||||
int ret;
|
||||
|
||||
ddata = dev_get_drvdata(dev);
|
||||
|
||||
ddata->regmap = regmap_init_slimbus(sdev, &wcd9335_regmap_config);
|
||||
if (IS_ERR(ddata->regmap)) {
|
||||
dev_err(dev, "Error allocating slim regmap\n");
|
||||
return PTR_ERR(ddata->regmap);
|
||||
}
|
||||
|
||||
ret = wcd9335_bring_up(ddata);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to bring up WCD9335: err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_regmap_add_irq_chip(dev, ddata->regmap, ddata->irq,
|
||||
IRQF_TRIGGER_HIGH, 0,
|
||||
&wcd9335_regmap_irq_chip,
|
||||
&ddata->irq_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to add IRQ chip: err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, wcd9335_devices,
|
||||
ARRAY_SIZE(wcd9335_devices), NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to add child devices: err = %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcd9335_slim_status(struct slim_device *sdev,
|
||||
enum slim_device_status status)
|
||||
{
|
||||
switch (status) {
|
||||
case SLIM_DEVICE_STATUS_UP:
|
||||
return wcd9335_slim_status_up(sdev);
|
||||
case SLIM_DEVICE_STATUS_DOWN:
|
||||
mfd_remove_devices(&sdev->dev);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd9335_slim_probe(struct slim_device *sdev)
|
||||
{
|
||||
struct device *dev = &sdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct wcd9335_ddata *ddata;
|
||||
int reset_gpio, ret;
|
||||
|
||||
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
return -ENOMEM;
|
||||
|
||||
ddata->irq = of_irq_get(np, 0);
|
||||
if (ddata->irq < 0)
|
||||
return dev_err_probe(ddata->dev, ddata->irq,
|
||||
"Failed to get IRQ\n");
|
||||
|
||||
reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
|
||||
if (reset_gpio < 0) {
|
||||
dev_err(dev, "Failed to get reset gpio: err = %d\n",
|
||||
reset_gpio);
|
||||
return reset_gpio;
|
||||
}
|
||||
|
||||
ddata->extclk = devm_clk_get(dev, "extclk");
|
||||
if (IS_ERR(ddata->extclk)) {
|
||||
dev_err(dev, "Failed to get extclk");
|
||||
return PTR_ERR(ddata->extclk);
|
||||
}
|
||||
|
||||
ddata->supplies[0].supply = "vdd-buck";
|
||||
ddata->supplies[1].supply = "vdd-buck-sido";
|
||||
ddata->supplies[2].supply = "vdd-tx";
|
||||
ddata->supplies[3].supply = "vdd-rx";
|
||||
ddata->supplies[4].supply = "vdd-io";
|
||||
|
||||
ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, ddata->supplies);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get supplies: err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, ddata->supplies);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable supplies: err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* For WCD9335, it takes about 600us for the Vout_A and
|
||||
* Vout_D to be ready after BUCK_SIDO is powered up.
|
||||
* SYS_RST_N shouldn't be pulled high during this time
|
||||
*/
|
||||
usleep_range(600, 650);
|
||||
gpio_direction_output(reset_gpio, 0);
|
||||
msleep(20);
|
||||
gpio_set_value(reset_gpio, 1);
|
||||
msleep(20);
|
||||
|
||||
ddata->dev = dev;
|
||||
dev_set_drvdata(dev, ddata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wcd9335_slim_remove(struct slim_device *sdev)
|
||||
{
|
||||
struct wcd9335_ddata *ddata = dev_get_drvdata(&sdev->dev);
|
||||
|
||||
regulator_bulk_disable(WCD9335_MAX_SUPPLY, ddata->supplies);
|
||||
mfd_remove_devices(&sdev->dev);
|
||||
}
|
||||
|
||||
static const struct slim_device_id wcd9335_slim_id[] = {
|
||||
{ SLIM_MANF_ID_QCOM, SLIM_PROD_CODE_WCD9340,
|
||||
SLIM_DEV_IDX_WCD9340, SLIM_DEV_INSTANCE_ID_WCD9340 },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct slim_driver wcd9335_slim_driver = {
|
||||
.driver = {
|
||||
.name = "wcd9335-slim",
|
||||
},
|
||||
.probe = wcd9335_slim_probe,
|
||||
.remove = wcd9335_slim_remove,
|
||||
.device_status = wcd9335_slim_status,
|
||||
.id_table = wcd9335_slim_id,
|
||||
};
|
||||
|
||||
module_slim_driver(wcd9335_slim_driver);
|
||||
MODULE_DESCRIPTION("WCD9335 slim driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("slim:217:250:*");
|
||||
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");
|
||||
|
|
@ -395,6 +395,7 @@ ipa_power_init(struct device *dev, const struct ipa_power_data *data)
|
|||
|
||||
pm_runtime_set_autosuspend_delay(dev, IPA_AUTOSUSPEND_DELAY);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_forbid(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return power;
|
||||
|
|
|
|||
|
|
@ -1004,6 +1004,8 @@ static void ath10k_qmi_driver_event_work(struct work_struct *work)
|
|||
switch (event->type) {
|
||||
case ATH10K_QMI_EVENT_SERVER_ARRIVE:
|
||||
ath10k_qmi_event_server_arrive(qmi);
|
||||
// HACK: Fake MSA being ready
|
||||
ath10k_qmi_event_msa_ready(qmi);
|
||||
break;
|
||||
case ATH10K_QMI_EVENT_SERVER_EXIT:
|
||||
ath10k_qmi_event_server_exit(qmi);
|
||||
|
|
|
|||
|
|
@ -127,6 +127,23 @@ config PINCTRL_AXP209
|
|||
selected.
|
||||
Say Y to enable pinctrl and GPIO support for the AXP209 PMIC.
|
||||
|
||||
config PINCTRL_AW9523
|
||||
bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver"
|
||||
depends on OF && I2C
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GENERIC_PINCONF
|
||||
select GPIOLIB
|
||||
select GPIOLIB_IRQCHIP
|
||||
select REGMAP_I2C
|
||||
help
|
||||
The Awinic AW9523/AW9523B is a multi-function I2C GPIO
|
||||
expander with PWM functionality. This driver bundles a
|
||||
pinctrl driver to select the function muxing and a GPIO
|
||||
driver to handle GPIO, when the GPIO function is selected.
|
||||
|
||||
Say yes to enable pinctrl and GPIO support for the AW9523(B).
|
||||
|
||||
config PINCTRL_BM1880
|
||||
bool "Bitmain BM1880 Pinctrl driver"
|
||||
depends on OF && (ARCH_BITMAIN || COMPILE_TEST)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl-artpec6.o
|
|||
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
|
||||
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
|
||||
obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
|
||||
obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o
|
||||
obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o
|
||||
obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
|
||||
obj-$(CONFIG_PINCTRL_CY8C95X0) += pinctrl-cy8c95x0.o
|
||||
|
|
|
|||
1125
drivers/pinctrl/pinctrl-aw9523.c
Normal file
1125
drivers/pinctrl/pinctrl-aw9523.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -918,4 +918,30 @@ config BATTERY_UG3105
|
|||
device is off or suspended, the functionality of this driver is
|
||||
limited to reporting capacity only.
|
||||
|
||||
config CHARGER_QCOM_SMB2
|
||||
tristate "Qualcomm PMI8998 PMIC charger driver"
|
||||
depends on MFD_SPMI_PMIC
|
||||
depends on IIO
|
||||
select QCOM_SPMI_RRADC
|
||||
help
|
||||
Driver for the "SMB2" charger block found on Qualcomm PMI8998
|
||||
and PM660 PMICs.
|
||||
|
||||
The charger features automatic power source detection via BC1.2,
|
||||
automatic input current limiting and reports the realtime voltage
|
||||
and current via the Round Robin ADC.
|
||||
|
||||
Say Y or M here to enable reporting the charger status and rate on
|
||||
supported platforms such as Snapdragon 845 and 835 based phones.
|
||||
|
||||
config BATTERY_QCOM_FG
|
||||
tristate "Qualcomm PMIC fuel gauge driver"
|
||||
depends on MFD_SPMI_PMIC
|
||||
help
|
||||
Say Y here to enable the Qualcomm PMIC Fuel Gauge driver. This
|
||||
adds support for battery fuel gauging and state of charge of
|
||||
battery connected to the fuel gauge. The state of charge is
|
||||
reported through a BMS power supply property and also sends
|
||||
uevents when the capacity is updated.
|
||||
|
||||
endif # POWER_SUPPLY
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
|
|||
obj-$(CONFIG_CHARGER_MP2629) += mp2629_charger.o
|
||||
obj-$(CONFIG_CHARGER_MT6360) += mt6360_charger.o
|
||||
obj-$(CONFIG_CHARGER_MT6370) += mt6370-charger.o
|
||||
obj-$(CONFIG_CHARGER_QCOM_SMB2) += qcom_pmi8998_charger.o
|
||||
obj-$(CONFIG_CHARGER_QCOM_SMBB) += qcom_smbb.o
|
||||
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
|
||||
obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o
|
||||
|
|
@ -110,3 +111,4 @@ obj-$(CONFIG_BATTERY_ACER_A500) += acer_a500_battery.o
|
|||
obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o
|
||||
obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.o
|
||||
obj-$(CONFIG_BATTERY_UG3105) += ug3105_battery.o
|
||||
obj-$(CONFIG_BATTERY_QCOM_FG) += qcom_fg.o
|
||||
|
|
|
|||
1159
drivers/power/supply/qcom_fg.c
Normal file
1159
drivers/power/supply/qcom_fg.c
Normal file
File diff suppressed because it is too large
Load diff
176
drivers/power/supply/qcom_fg.h
Normal file
176
drivers/power/supply/qcom_fg.h
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
|
||||
// #define FG_PARAM_MAX 49
|
||||
|
||||
/**** Registers *****/
|
||||
|
||||
#define PMIC_SUBTYPE 0x105
|
||||
|
||||
#define PMI8994_SUBTYPE 0x0a
|
||||
#define PMI8996_SUBTYPE 0x13
|
||||
#define PM8998_SUBTYPE 0x14
|
||||
#define PMI8998_SUBTYPE 0x15
|
||||
|
||||
|
||||
/* SRAM */
|
||||
#define MEM_INTF_STS 0x10
|
||||
#define MEM_INTF_CFG 0x50
|
||||
#define MEM_INTF_CTL 0x51
|
||||
#define MEM_INTF_IMA_CFG 0x52
|
||||
#define MEM_INTF_IMA_OPR_STS 0x54
|
||||
#define MEM_INTF_IMA_EXP_STS 0x55
|
||||
#define MEM_INTF_IMA_HW_STS 0x56
|
||||
#define MEM_INTF_BEAT_COUNT 0x57
|
||||
#define MEM_INTF_IMA_ERR_STS 0x5f
|
||||
#define MEM_INTF_IMA_BYTE_EN 0x60
|
||||
#define MEM_INTF_ADDR_LSB 0x61
|
||||
#define MEM_INTF_RD_DATA0 0x67
|
||||
#define MEM_INTF_WR_DATA0 0x63
|
||||
|
||||
#define MEM_INTF_AVAIL BIT(0)
|
||||
#define MEM_INTF_CTL_BURST BIT(7)
|
||||
#define MEM_INTF_CTL_WR_EN BIT(6)
|
||||
#define RIF_MEM_ACCESS_REQ BIT(7)
|
||||
|
||||
|
||||
/* Battery info */
|
||||
#define BATT_INFO_CHARGE_MAX_DESIGN 0x4a
|
||||
#define BATT_INFO_THERM_C1 0x5c
|
||||
#define BATT_INFO_VBATT_LSB 0xa0
|
||||
#define BATT_INFO_VBATT_MSB 0xa1
|
||||
#define BATT_INFO_IBATT_LSB 0xa2
|
||||
#define BATT_INFO_IBATT_MSB 0xa3
|
||||
#define BATT_INFO_BATT_TEMP_LSB 0x50
|
||||
#define BATT_INFO_BATT_TEMP_MSB 0x51
|
||||
#define BATT_MONOTONIC_SOC 0x09
|
||||
|
||||
#define BATT_TEMP_LSB_MASK GENMASK(7, 0)
|
||||
#define BATT_TEMP_MSB_MASK GENMASK(2, 0)
|
||||
|
||||
|
||||
/* Base addresses */
|
||||
#define REG_BASE 0x4000
|
||||
#define REG_BATT 0x4100
|
||||
#define REG_MEM 0x4400
|
||||
|
||||
|
||||
/* Interrupt offsets */
|
||||
#define INT_RT_STS 0x10
|
||||
#define INT_EN_CLR 0x16
|
||||
|
||||
|
||||
/* Param addresses */
|
||||
#define PARAM_ADDR_BATT_TEMP 0x50
|
||||
#define PARAM_ADDR_BATT_VOLTAGE 0xa0
|
||||
#define PARAM_ADDR_BATT_CURRENT 0xa2
|
||||
|
||||
|
||||
#define MISC_BASE 0x1600
|
||||
#define USBIN_BASE 0x1300
|
||||
|
||||
|
||||
#define BATT_INFO_JEITA_COLD(chip) (REG_BATT + 0x62)
|
||||
#define BATT_INFO_JEITA_COOL(chip) (REG_BATT + 0x63)
|
||||
#define BATT_INFO_JEITA_WARM(chip) (REG_BATT + 0x64)
|
||||
#define BATT_INFO_JEITA_HOT(chip) (REG_BATT + 0x65)
|
||||
|
||||
#define BATT_TEMP_JEITA_COLD 100
|
||||
#define BATT_TEMP_JEITA_COOL 50
|
||||
#define BATT_TEMP_JEITA_WARM 400
|
||||
#define BATT_TEMP_JEITA_HOT 450
|
||||
|
||||
#define BATTERY_CHARGER_STATUS_REG(chip) (chip->chg_base + 0x06)
|
||||
#define BATTERY_HEALTH_STATUS_REG(chip) (chip->chg_base + 0x07)
|
||||
|
||||
#define BATTERY_CHARGER_STATUS_MASK GENMASK(2, 0)
|
||||
#define POWER_PATH_STATUS_REG (MISC_BASE + 0x0B)
|
||||
|
||||
#define MEM_IF_TIMEOUT_MS 5000
|
||||
|
||||
enum wa_flags {
|
||||
PMI8998_V1_REV_WA,
|
||||
PMI8998_V2_REV_WA,
|
||||
};
|
||||
|
||||
enum pmic_rev_offsets {
|
||||
DIG_MINOR = 0x0,
|
||||
DIG_MAJOR = 0x1,
|
||||
ANA_MINOR = 0x2,
|
||||
ANA_MAJOR = 0x3,
|
||||
};
|
||||
enum pmic_rev {
|
||||
DIG_REV_1 = 0x1,
|
||||
DIG_REV_2 = 0x2,
|
||||
DIG_REV_3 = 0x3,
|
||||
};
|
||||
|
||||
enum charger_status{
|
||||
TRICKLE_CHARGE = 0,
|
||||
PRE_CHARGE,
|
||||
FAST_CHARGE,
|
||||
FULLON_CHARGE,
|
||||
TAPER_CHARGE,
|
||||
TERMINATE_CHARGE,
|
||||
INHIBIT_CHARGE,
|
||||
DISABLE_CHARGE,
|
||||
};
|
||||
|
||||
static enum power_supply_property fg_properties[] = {
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_CHARGE_FULL,
|
||||
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
|
||||
POWER_SUPPLY_PROP_TEMP,
|
||||
POWER_SUPPLY_PROP_TEMP_MIN,
|
||||
POWER_SUPPLY_PROP_TEMP_MAX,
|
||||
POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
|
||||
POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
|
||||
};
|
||||
|
||||
struct qcom_fg_chip;
|
||||
|
||||
struct qcom_fg_ops {
|
||||
int (*get_capacity)(struct qcom_fg_chip *chip, int *);
|
||||
int (*get_temperature)(struct qcom_fg_chip *chip, int *);
|
||||
int (*get_current)(struct qcom_fg_chip *chip, int *);
|
||||
int (*get_voltage)(struct qcom_fg_chip *chip, int *);
|
||||
int (*get_batt_status)(struct qcom_fg_chip *chip, int *);
|
||||
int (*get_health_status)(struct qcom_fg_chip *chip, int *);
|
||||
int (*get_temp_threshold)(struct qcom_fg_chip *chip,
|
||||
enum power_supply_property psp, int *);
|
||||
int (*set_temp_threshold)(struct qcom_fg_chip *chip,
|
||||
enum power_supply_property psp, int);
|
||||
};
|
||||
|
||||
struct qcom_fg_chip {
|
||||
struct device *dev;
|
||||
unsigned int base;
|
||||
unsigned int chg_base;
|
||||
struct regmap *regmap;
|
||||
struct mutex lock;
|
||||
unsigned int subtype;
|
||||
const struct qcom_fg_ops *ops;
|
||||
|
||||
struct power_supply *bms_psy;
|
||||
|
||||
u8 revision[4];
|
||||
bool ima_supported;
|
||||
struct completion sram_access_granted;
|
||||
|
||||
int batt_cap_uah;
|
||||
int batt_max_voltage_uv;
|
||||
int batt_min_voltage_uv;
|
||||
|
||||
int health;
|
||||
int status;
|
||||
bool online;
|
||||
};
|
||||
1082
drivers/power/supply/qcom_pmi8998_charger.c
Normal file
1082
drivers/power/supply/qcom_pmi8998_charger.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -279,12 +279,6 @@ static irqreturn_t qcom_labibb_ocp_isr(int irq, void *chip)
|
|||
}
|
||||
vreg->ocp_irq_count++;
|
||||
|
||||
/*
|
||||
* Disable the interrupt temporarily, or it will fire continuously;
|
||||
* we will re-enable it in the recovery worker function.
|
||||
*/
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
/* Warn the user for overcurrent */
|
||||
dev_warn(vreg->dev, "Over-Current interrupt fired!\n");
|
||||
|
||||
|
|
@ -304,6 +298,12 @@ end:
|
|||
if (ret)
|
||||
return IRQ_NONE;
|
||||
|
||||
/*
|
||||
* Disable the interrupt temporarily, or it will fire continuously;
|
||||
* we will re-enable it in the recovery worker function.
|
||||
*/
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
@ -316,8 +316,11 @@ static int qcom_labibb_set_ocp(struct regulator_dev *rdev, int lim,
|
|||
int irq_trig_low, ret;
|
||||
|
||||
/*
|
||||
* labibb supports only protection - and does not support setting
|
||||
* limit. Furthermore, we don't support disabling protection.
|
||||
* labibb does not support specifying a current limit that is
|
||||
* special to over-current protection, but only a global one
|
||||
* that will be used for both current limiting and protection;
|
||||
* for this reason, we only support enabling the OCP here.
|
||||
* Furthermore, we don't support disabling protection.
|
||||
*/
|
||||
if (lim || severity != REGULATOR_SEVERITY_PROT || !enable)
|
||||
return -EINVAL;
|
||||
|
|
@ -540,12 +543,6 @@ static irqreturn_t qcom_labibb_sc_isr(int irq, void *chip)
|
|||
/* Warn the user for short circuit */
|
||||
dev_warn(vreg->dev, "Short-Circuit interrupt fired!\n");
|
||||
|
||||
/*
|
||||
* Disable the interrupt temporarily, or it will fire continuously;
|
||||
* we will re-enable it in the recovery worker function.
|
||||
*/
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
/* Signal out of regulation event to drivers */
|
||||
regulator_notifier_call_chain(vreg->rdev,
|
||||
REGULATOR_EVENT_REGULATION_OUT, NULL);
|
||||
|
|
@ -553,6 +550,13 @@ static irqreturn_t qcom_labibb_sc_isr(int irq, void *chip)
|
|||
/* Schedule the short-circuit handling as high-priority work */
|
||||
mod_delayed_work(system_highpri_wq, &vreg->sc_recovery_work,
|
||||
msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
|
||||
|
||||
/*
|
||||
* Disable the interrupt temporarily, or it will fire continuously;
|
||||
* we will re-enable it in the recovery worker function.
|
||||
*/
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,23 @@ config QCOM_CPR
|
|||
To compile this driver as a module, choose M here: the module will
|
||||
be called qcom-cpr
|
||||
|
||||
config QCOM_CPR3
|
||||
tristate "QCOM Core Power Reduction (CPR v3/v4/Hardened) support"
|
||||
depends on ARCH_QCOM && HAS_IOMEM
|
||||
select PM_OPP
|
||||
select REGMAP
|
||||
help
|
||||
Say Y here to enable support for the CPR hardware found on a broad
|
||||
variety of Qualcomm SoCs like MSM8996, MSM8998, SDM630, SDM660,
|
||||
SDM845 and others.
|
||||
|
||||
This driver populates OPP tables and makes adjustments to them
|
||||
based on feedback from the CPR hardware. If you want to do CPU
|
||||
and/or GPU frequency scaling say Y here.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called qcom-cpr3
|
||||
|
||||
config QCOM_GENI_SE
|
||||
tristate "QCOM GENI Serial Engine Driver"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ CFLAGS_rpmh-rsc.o := -I$(src)
|
|||
obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
|
||||
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
|
||||
obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
|
||||
obj-$(CONFIG_QCOM_CPR) += cpr.o
|
||||
obj-$(CONFIG_QCOM_CPR) += cpr-common.o cpr.o
|
||||
obj-$(CONFIG_QCOM_CPR3) += cpr-common.o cpr3.o
|
||||
obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
|
||||
obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
|
||||
obj-$(CONFIG_QCOM_OCMEM) += ocmem.o
|
||||
|
|
|
|||
372
drivers/soc/qcom/cpr-common.c
Normal file
372
drivers/soc/qcom/cpr-common.c
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019, Linaro Limited
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include "cpr-common.h"
|
||||
|
||||
int cpr_populate_ring_osc_idx(struct device *dev,
|
||||
struct fuse_corner *fuse_corner,
|
||||
const struct cpr_fuse *cpr_fuse,
|
||||
int num_fuse_corners)
|
||||
{
|
||||
struct fuse_corner *end = fuse_corner + num_fuse_corners;
|
||||
u32 data;
|
||||
int ret;
|
||||
|
||||
for (; fuse_corner < end; fuse_corner++, cpr_fuse++) {
|
||||
ret = nvmem_cell_read_variable_le_u32(dev, cpr_fuse->ring_osc, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
fuse_corner->ring_osc_idx = data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpr_read_fuse_uV(int init_v_width, int step_size_uV, int ref_uV,
|
||||
int adj, int step_volt, const char *init_v_efuse,
|
||||
struct device *dev)
|
||||
{
|
||||
int steps, uV;
|
||||
u32 bits = 0;
|
||||
int ret;
|
||||
|
||||
ret = nvmem_cell_read_variable_le_u32(dev, init_v_efuse, &bits);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
steps = bits & (BIT(init_v_width - 1) - 1);
|
||||
/* Not two's complement.. instead highest bit is sign bit */
|
||||
if (bits & BIT(init_v_width - 1))
|
||||
steps = -steps;
|
||||
|
||||
uV = ref_uV + steps * step_size_uV;
|
||||
|
||||
/* Apply open-loop fixed adjustments to fused values */
|
||||
uV += adj;
|
||||
|
||||
return DIV_ROUND_UP(uV, step_volt) * step_volt;
|
||||
}
|
||||
|
||||
const struct cpr_fuse *cpr_get_fuses(struct device *dev, int tid,
|
||||
int num_fuse_corners)
|
||||
{
|
||||
struct cpr_fuse *fuses;
|
||||
int i;
|
||||
|
||||
fuses = devm_kcalloc(dev, num_fuse_corners,
|
||||
sizeof(struct cpr_fuse),
|
||||
GFP_KERNEL);
|
||||
if (!fuses)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
for (i = 0; i < num_fuse_corners; i++) {
|
||||
char tbuf[50];
|
||||
|
||||
snprintf(tbuf, sizeof(tbuf), "cpr%d_ring_osc%d", tid, i + 1);
|
||||
fuses[i].ring_osc = devm_kstrdup(dev, tbuf, GFP_KERNEL);
|
||||
if (!fuses[i].ring_osc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
snprintf(tbuf, sizeof(tbuf),
|
||||
"cpr%d_init_voltage%d", tid, i + 1);
|
||||
fuses[i].init_voltage = devm_kstrdup(dev, tbuf,
|
||||
GFP_KERNEL);
|
||||
if (!fuses[i].init_voltage)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
snprintf(tbuf, sizeof(tbuf), "cpr%d_quotient%d", tid, i + 1);
|
||||
fuses[i].quotient = devm_kstrdup(dev, tbuf, GFP_KERNEL);
|
||||
if (!fuses[i].quotient)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
snprintf(tbuf, sizeof(tbuf),
|
||||
"cpr%d_quotient_offset%d", tid, i + 1);
|
||||
fuses[i].quotient_offset = devm_kstrdup(dev, tbuf,
|
||||
GFP_KERNEL);
|
||||
if (!fuses[i].quotient_offset)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
return fuses;
|
||||
}
|
||||
|
||||
int cpr_populate_fuse_common(struct device *dev,
|
||||
struct fuse_corner_data *fdata,
|
||||
const struct cpr_fuse *cpr_fuse,
|
||||
struct fuse_corner *fuse_corner,
|
||||
int step_volt, int init_v_width,
|
||||
int init_v_step)
|
||||
{
|
||||
int uV, ret;
|
||||
|
||||
/* Populate uV */
|
||||
uV = cpr_read_fuse_uV(init_v_width, init_v_step,
|
||||
fdata->ref_uV, fdata->volt_oloop_adjust,
|
||||
step_volt, cpr_fuse->init_voltage, dev);
|
||||
if (uV < 0)
|
||||
return uV;
|
||||
|
||||
/*
|
||||
* Update SoC voltages: platforms might choose a different
|
||||
* regulators than the one used to characterize the algorithms
|
||||
* (ie, init_voltage_step).
|
||||
*/
|
||||
fdata->min_uV = roundup(fdata->min_uV, step_volt);
|
||||
fdata->max_uV = roundup(fdata->max_uV, step_volt);
|
||||
|
||||
fuse_corner->min_uV = fdata->min_uV;
|
||||
fuse_corner->max_uV = fdata->max_uV;
|
||||
fuse_corner->uV = clamp(uV, fuse_corner->min_uV, fuse_corner->max_uV);
|
||||
|
||||
/* Populate target quotient by scaling */
|
||||
ret = nvmem_cell_read_variable_le_u32(dev, cpr_fuse->quotient, &fuse_corner->quot);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fuse_corner->quot *= fdata->quot_scale;
|
||||
fuse_corner->quot += fdata->quot_offset;
|
||||
fuse_corner->quot += fdata->quot_adjust;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns: Index of the initial corner or negative number for error.
|
||||
*/
|
||||
int cpr_find_initial_corner(struct device *dev, struct clk *cpu_clk,
|
||||
struct corner *corners, int num_corners)
|
||||
{
|
||||
unsigned long rate;
|
||||
struct corner *iter, *corner;
|
||||
const struct corner *end;
|
||||
unsigned int ret = 0;
|
||||
|
||||
if (!cpu_clk)
|
||||
return -EINVAL;
|
||||
|
||||
end = &corners[num_corners - 1];
|
||||
rate = clk_get_rate(cpu_clk);
|
||||
|
||||
/*
|
||||
* Some bootloaders set a CPU clock frequency that is not defined
|
||||
* in the OPP table. When running at an unlisted frequency,
|
||||
* cpufreq_online() will change to the OPP which has the lowest
|
||||
* frequency, at or above the unlisted frequency.
|
||||
* Since cpufreq_online() always "rounds up" in the case of an
|
||||
* unlisted frequency, this function always "rounds down" in case
|
||||
* of an unlisted frequency. That way, when cpufreq_online()
|
||||
* triggers the first ever call to cpr_set_performance_state(),
|
||||
* it will correctly determine the direction as UP.
|
||||
*/
|
||||
for (iter = corners; iter <= end; iter++) {
|
||||
if (iter->freq > rate)
|
||||
break;
|
||||
ret++;
|
||||
if (iter->freq == rate) {
|
||||
corner = iter;
|
||||
break;
|
||||
}
|
||||
if (iter->freq < rate)
|
||||
corner = iter;
|
||||
}
|
||||
|
||||
if (!corner) {
|
||||
dev_err(dev, "boot up corner not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "boot up perf state: %u\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 cpr_get_fuse_corner(struct dev_pm_opp *opp, u32 tid)
|
||||
{
|
||||
struct device_node *np;
|
||||
u32 fc;
|
||||
|
||||
np = dev_pm_opp_get_of_node(opp);
|
||||
if (of_property_read_u32_index(np, "qcom,opp-fuse-level", tid, &fc)) {
|
||||
pr_debug("%s: missing 'qcom,opp-fuse-level' property\n",
|
||||
__func__);
|
||||
fc = 0;
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
return fc;
|
||||
|
||||
}
|
||||
|
||||
void cpr_get_corner_post_vadj(struct dev_pm_opp *opp, u32 tid,
|
||||
s32 *open_loop, s32 *closed_loop)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
/*
|
||||
* There is no of_property_read_s32_index, so we just store the
|
||||
* result into a s32 variable. After all, the OF API is doing
|
||||
* the exact same for of_property_read_s32...
|
||||
*/
|
||||
np = dev_pm_opp_get_of_node(opp);
|
||||
if (of_property_read_u32_index(np, "qcom,opp-oloop-vadj", tid,
|
||||
open_loop))
|
||||
*open_loop = 0;
|
||||
|
||||
if (of_property_read_u32_index(np, "qcom,opp-cloop-vadj", tid,
|
||||
closed_loop))
|
||||
*closed_loop = 0;
|
||||
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref,
|
||||
struct device *cpu_dev)
|
||||
{
|
||||
u64 rate = 0;
|
||||
struct device_node *ref_np;
|
||||
struct device_node *desc_np;
|
||||
struct device_node *child_np = NULL;
|
||||
struct device_node *child_req_np = NULL;
|
||||
|
||||
desc_np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
|
||||
if (!desc_np)
|
||||
return 0;
|
||||
|
||||
ref_np = dev_pm_opp_get_of_node(ref);
|
||||
if (!ref_np)
|
||||
goto out_ref;
|
||||
|
||||
do {
|
||||
of_node_put(child_req_np);
|
||||
child_np = of_get_next_available_child(desc_np, child_np);
|
||||
child_req_np = of_parse_phandle(child_np, "required-opps", 0);
|
||||
} while (child_np && child_req_np != ref_np);
|
||||
|
||||
if (child_np && child_req_np == ref_np)
|
||||
of_property_read_u64(child_np, "opp-hz", &rate);
|
||||
|
||||
of_node_put(child_req_np);
|
||||
of_node_put(child_np);
|
||||
of_node_put(ref_np);
|
||||
out_ref:
|
||||
of_node_put(desc_np);
|
||||
|
||||
return (unsigned long) rate;
|
||||
}
|
||||
|
||||
int cpr_calculate_scaling(const char *quot_offset,
|
||||
struct device *dev,
|
||||
const struct fuse_corner_data *fdata,
|
||||
const struct corner *corner)
|
||||
{
|
||||
u64 freq_diff;
|
||||
const struct fuse_corner *fuse, *prev_fuse;
|
||||
u32 quot_diff;
|
||||
int scaling, ret;
|
||||
|
||||
fuse = corner->fuse_corner;
|
||||
prev_fuse = fuse - 1;
|
||||
|
||||
if (quot_offset) {
|
||||
ret = nvmem_cell_read_variable_le_u32(dev, quot_offset, "_diff);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
quot_diff *= fdata->quot_offset_scale;
|
||||
quot_diff += fdata->quot_offset_adjust;
|
||||
} else {
|
||||
quot_diff = fuse->quot - prev_fuse->quot;
|
||||
}
|
||||
|
||||
freq_diff = fuse->max_freq - prev_fuse->max_freq;
|
||||
freq_diff = div_u64(freq_diff, 1000000); /* Convert to MHz */
|
||||
scaling = 1000 * quot_diff;
|
||||
do_div(scaling, freq_diff);
|
||||
return min(scaling, fdata->max_quot_scale);
|
||||
}
|
||||
|
||||
int cpr_interpolate(const struct corner *corner, int step_volt,
|
||||
const struct fuse_corner_data *fdata)
|
||||
{
|
||||
unsigned long f_high, f_low, f_diff;
|
||||
int uV_high, uV_low, uV;
|
||||
u64 temp, temp_limit;
|
||||
const struct fuse_corner *fuse, *prev_fuse;
|
||||
|
||||
fuse = corner->fuse_corner;
|
||||
prev_fuse = fuse - 1;
|
||||
|
||||
f_high = fuse->max_freq;
|
||||
f_low = prev_fuse->max_freq;
|
||||
uV_high = fuse->uV;
|
||||
uV_low = prev_fuse->uV;
|
||||
f_diff = fuse->max_freq - corner->freq;
|
||||
|
||||
/*
|
||||
* Don't interpolate in the wrong direction. This could happen
|
||||
* if the adjusted fuse voltage overlaps with the previous fuse's
|
||||
* adjusted voltage.
|
||||
*/
|
||||
if (f_high <= f_low || uV_high <= uV_low || f_high <= corner->freq)
|
||||
return corner->uV;
|
||||
|
||||
temp = f_diff * (uV_high - uV_low);
|
||||
temp = div64_ul(temp, f_high - f_low);
|
||||
|
||||
/*
|
||||
* max_volt_scale has units of uV/MHz while freq values
|
||||
* have units of Hz. Divide by 1000000 to convert to.
|
||||
*/
|
||||
temp_limit = f_diff * fdata->max_volt_scale;
|
||||
do_div(temp_limit, 1000000);
|
||||
|
||||
uV = uV_high - min(temp, temp_limit);
|
||||
return roundup(uV, step_volt);
|
||||
}
|
||||
|
||||
int cpr_check_vreg_constraints(struct device *dev, struct regulator *vreg,
|
||||
struct fuse_corner *f)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regulator_is_supported_voltage(vreg, f->min_uV, f->min_uV);
|
||||
if (!ret) {
|
||||
dev_err(dev, "min uV: %d not supported by regulator\n",
|
||||
f->min_uV);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regulator_is_supported_voltage(vreg, f->max_uV, f->max_uV);
|
||||
if (!ret) {
|
||||
dev_err(dev, "max uV: %d not supported by regulator\n",
|
||||
f->max_uV);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
117
drivers/soc/qcom/cpr-common.h
Normal file
117
drivers/soc/qcom/cpr-common.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
enum voltage_change_dir {
|
||||
NO_CHANGE,
|
||||
DOWN,
|
||||
UP,
|
||||
};
|
||||
|
||||
struct fuse_corner_data {
|
||||
int ref_uV;
|
||||
int max_uV;
|
||||
int min_uV;
|
||||
int range_uV;
|
||||
/* fuse volt: closed/open loop */
|
||||
int volt_cloop_adjust;
|
||||
int volt_oloop_adjust;
|
||||
int max_volt_scale;
|
||||
int max_quot_scale;
|
||||
/* fuse quot */
|
||||
int quot_offset;
|
||||
int quot_scale;
|
||||
int quot_adjust;
|
||||
/* fuse quot_offset */
|
||||
int quot_offset_scale;
|
||||
int quot_offset_adjust;
|
||||
};
|
||||
|
||||
struct cpr_fuse {
|
||||
char *ring_osc;
|
||||
char *init_voltage;
|
||||
char *quotient;
|
||||
char *quotient_offset;
|
||||
};
|
||||
|
||||
struct fuse_corner {
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
int uV;
|
||||
int quot;
|
||||
int step_quot;
|
||||
const struct reg_sequence *accs;
|
||||
int num_accs;
|
||||
unsigned long max_freq;
|
||||
u8 ring_osc_idx;
|
||||
};
|
||||
|
||||
struct corner {
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
int uV;
|
||||
int last_uV;
|
||||
int quot_adjust;
|
||||
u32 save_ctl;
|
||||
u32 save_irq;
|
||||
unsigned long freq;
|
||||
bool is_open_loop;
|
||||
struct fuse_corner *fuse_corner;
|
||||
};
|
||||
|
||||
struct corner_data {
|
||||
unsigned int fuse_corner;
|
||||
unsigned long freq;
|
||||
int oloop_vadj;
|
||||
int cloop_vadj;
|
||||
};
|
||||
|
||||
struct acc_desc {
|
||||
unsigned int enable_reg;
|
||||
u32 enable_mask;
|
||||
|
||||
struct reg_sequence *config;
|
||||
struct reg_sequence *settings;
|
||||
int num_regs_per_fuse;
|
||||
};
|
||||
|
||||
struct cpr_acc_desc {
|
||||
const struct cpr_desc *cpr_desc;
|
||||
const struct acc_desc *acc_desc;
|
||||
};
|
||||
|
||||
|
||||
int cpr_read_efuse(struct device *dev, const char *cname, u32 *data);
|
||||
int cpr_populate_ring_osc_idx(struct device *dev,
|
||||
struct fuse_corner *fuse_corner,
|
||||
const struct cpr_fuse *cpr_fuse,
|
||||
int num_fuse_corners);
|
||||
int cpr_read_fuse_uV(int init_v_width, int step_size_uV, int ref_uV,
|
||||
int adj, int step_volt, const char *init_v_efuse,
|
||||
struct device *dev);
|
||||
const struct cpr_fuse *cpr_get_fuses(struct device *dev, int tid,
|
||||
int num_fuse_corners);
|
||||
int cpr_populate_fuse_common(struct device *dev,
|
||||
struct fuse_corner_data *fdata,
|
||||
const struct cpr_fuse *cpr_fuse,
|
||||
struct fuse_corner *fuse_corner,
|
||||
int step_volt, int init_v_width,
|
||||
int init_v_step);
|
||||
int cpr_find_initial_corner(struct device *dev, struct clk *cpu_clk,
|
||||
struct corner *corners, int num_corners);
|
||||
u32 cpr_get_fuse_corner(struct dev_pm_opp *opp, u32 tid);
|
||||
void cpr_get_corner_post_vadj(struct dev_pm_opp *opp, u32 tid,
|
||||
s32 *open_loop, s32 *closed_loop);
|
||||
unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref,
|
||||
struct device *cpu_dev);
|
||||
int cpr_calculate_scaling(const char *quot_offset,
|
||||
struct device *dev,
|
||||
const struct fuse_corner_data *fdata,
|
||||
const struct corner *corner);
|
||||
int cpr_interpolate(const struct corner *corner, int step_volt,
|
||||
const struct fuse_corner_data *fdata);
|
||||
int cpr_check_vreg_constraints(struct device *dev, struct regulator *vreg,
|
||||
struct fuse_corner *f);
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include "cpr-common.h"
|
||||
|
||||
/* Register Offsets for RB-CPR and Bit Definitions */
|
||||
|
||||
|
|
@ -124,45 +125,12 @@
|
|||
|
||||
#define FUSE_REVISION_UNKNOWN (-1)
|
||||
|
||||
enum voltage_change_dir {
|
||||
NO_CHANGE,
|
||||
DOWN,
|
||||
UP,
|
||||
};
|
||||
|
||||
struct cpr_fuse {
|
||||
char *ring_osc;
|
||||
char *init_voltage;
|
||||
char *quotient;
|
||||
char *quotient_offset;
|
||||
};
|
||||
|
||||
struct fuse_corner_data {
|
||||
int ref_uV;
|
||||
int max_uV;
|
||||
int min_uV;
|
||||
int max_volt_scale;
|
||||
int max_quot_scale;
|
||||
/* fuse quot */
|
||||
int quot_offset;
|
||||
int quot_scale;
|
||||
int quot_adjust;
|
||||
/* fuse quot_offset */
|
||||
int quot_offset_scale;
|
||||
int quot_offset_adjust;
|
||||
};
|
||||
|
||||
struct cpr_fuses {
|
||||
int init_voltage_step;
|
||||
int init_voltage_width;
|
||||
struct fuse_corner_data *fuse_corner_data;
|
||||
};
|
||||
|
||||
struct corner_data {
|
||||
unsigned int fuse_corner;
|
||||
unsigned long freq;
|
||||
};
|
||||
|
||||
struct cpr_desc {
|
||||
unsigned int num_fuse_corners;
|
||||
int min_diff_quot;
|
||||
|
|
@ -184,44 +152,6 @@ struct cpr_desc {
|
|||
bool reduce_to_corner_uV;
|
||||
};
|
||||
|
||||
struct acc_desc {
|
||||
unsigned int enable_reg;
|
||||
u32 enable_mask;
|
||||
|
||||
struct reg_sequence *config;
|
||||
struct reg_sequence *settings;
|
||||
int num_regs_per_fuse;
|
||||
};
|
||||
|
||||
struct cpr_acc_desc {
|
||||
const struct cpr_desc *cpr_desc;
|
||||
const struct acc_desc *acc_desc;
|
||||
};
|
||||
|
||||
struct fuse_corner {
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
int uV;
|
||||
int quot;
|
||||
int step_quot;
|
||||
const struct reg_sequence *accs;
|
||||
int num_accs;
|
||||
unsigned long max_freq;
|
||||
u8 ring_osc_idx;
|
||||
};
|
||||
|
||||
struct corner {
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
int uV;
|
||||
int last_uV;
|
||||
int quot_adjust;
|
||||
u32 save_ctl;
|
||||
u32 save_irq;
|
||||
unsigned long freq;
|
||||
struct fuse_corner *fuse_corner;
|
||||
};
|
||||
|
||||
struct cpr_drv {
|
||||
unsigned int num_corners;
|
||||
unsigned int ref_clk_khz;
|
||||
|
|
@ -801,62 +731,16 @@ unlock:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
cpr_populate_ring_osc_idx(struct cpr_drv *drv)
|
||||
{
|
||||
struct fuse_corner *fuse = drv->fuse_corners;
|
||||
struct fuse_corner *end = fuse + drv->desc->num_fuse_corners;
|
||||
const struct cpr_fuse *fuses = drv->cpr_fuses;
|
||||
u32 data;
|
||||
int ret;
|
||||
|
||||
for (; fuse < end; fuse++, fuses++) {
|
||||
ret = nvmem_cell_read_variable_le_u32(drv->dev, fuses->ring_osc, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
fuse->ring_osc_idx = data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpr_read_fuse_uV(const struct cpr_desc *desc,
|
||||
const struct fuse_corner_data *fdata,
|
||||
const char *init_v_efuse,
|
||||
int step_volt,
|
||||
struct cpr_drv *drv)
|
||||
{
|
||||
int step_size_uV, steps, uV;
|
||||
u32 bits = 0;
|
||||
int ret;
|
||||
|
||||
ret = nvmem_cell_read_variable_le_u32(drv->dev, init_v_efuse, &bits);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
steps = bits & ~BIT(desc->cpr_fuses.init_voltage_width - 1);
|
||||
/* Not two's complement.. instead highest bit is sign bit */
|
||||
if (bits & BIT(desc->cpr_fuses.init_voltage_width - 1))
|
||||
steps = -steps;
|
||||
|
||||
step_size_uV = desc->cpr_fuses.init_voltage_step;
|
||||
|
||||
uV = fdata->ref_uV + steps * step_size_uV;
|
||||
return DIV_ROUND_UP(uV, step_volt) * step_volt;
|
||||
}
|
||||
|
||||
static int cpr_fuse_corner_init(struct cpr_drv *drv)
|
||||
{
|
||||
const struct cpr_desc *desc = drv->desc;
|
||||
const struct cpr_fuse *fuses = drv->cpr_fuses;
|
||||
const struct cpr_fuse *cpr_fuse = drv->cpr_fuses;
|
||||
const struct acc_desc *acc_desc = drv->acc_desc;
|
||||
int i;
|
||||
unsigned int step_volt;
|
||||
struct fuse_corner_data *fdata;
|
||||
struct fuse_corner *fuse, *end;
|
||||
int uV;
|
||||
const struct reg_sequence *accs;
|
||||
int ret;
|
||||
unsigned int step_volt;
|
||||
int i, ret;
|
||||
|
||||
accs = acc_desc->settings;
|
||||
|
||||
|
|
@ -869,24 +753,16 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
|
|||
end = &fuse[desc->num_fuse_corners - 1];
|
||||
fdata = desc->cpr_fuses.fuse_corner_data;
|
||||
|
||||
for (i = 0; fuse <= end; fuse++, fuses++, i++, fdata++) {
|
||||
/*
|
||||
* Update SoC voltages: platforms might choose a different
|
||||
* regulators than the one used to characterize the algorithms
|
||||
* (ie, init_voltage_step).
|
||||
*/
|
||||
fdata->min_uV = roundup(fdata->min_uV, step_volt);
|
||||
fdata->max_uV = roundup(fdata->max_uV, step_volt);
|
||||
for (i = 0; fuse <= end; fuse++, cpr_fuse++, i++, fdata++) {
|
||||
ret = cpr_populate_fuse_common(
|
||||
drv->dev, fdata, cpr_fuse,
|
||||
fuse, step_volt,
|
||||
desc->cpr_fuses.init_voltage_width,
|
||||
desc->cpr_fuses.init_voltage_step);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Populate uV */
|
||||
uV = cpr_read_fuse_uV(desc, fdata, fuses->init_voltage,
|
||||
step_volt, drv);
|
||||
if (uV < 0)
|
||||
return uV;
|
||||
|
||||
fuse->min_uV = fdata->min_uV;
|
||||
fuse->max_uV = fdata->max_uV;
|
||||
fuse->uV = clamp(uV, fuse->min_uV, fuse->max_uV);
|
||||
fuse->step_quot = desc->step_quot[fuse->ring_osc_idx];
|
||||
|
||||
if (fuse == end) {
|
||||
/*
|
||||
|
|
@ -898,16 +774,6 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
|
|||
end->max_uV = max(end->max_uV, end->uV);
|
||||
}
|
||||
|
||||
/* Populate target quotient by scaling */
|
||||
ret = nvmem_cell_read_variable_le_u32(drv->dev, fuses->quotient, &fuse->quot);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fuse->quot *= fdata->quot_scale;
|
||||
fuse->quot += fdata->quot_offset;
|
||||
fuse->quot += fdata->quot_adjust;
|
||||
fuse->step_quot = desc->step_quot[fuse->ring_osc_idx];
|
||||
|
||||
/* Populate acc settings */
|
||||
fuse->accs = accs;
|
||||
fuse->num_accs = acc_desc->num_regs_per_fuse;
|
||||
|
|
@ -924,25 +790,9 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
|
|||
else if (fuse->uV < fuse->min_uV)
|
||||
fuse->uV = fuse->min_uV;
|
||||
|
||||
ret = regulator_is_supported_voltage(drv->vdd_apc,
|
||||
fuse->min_uV,
|
||||
fuse->min_uV);
|
||||
if (!ret) {
|
||||
dev_err(drv->dev,
|
||||
"min uV: %d (fuse corner: %d) not supported by regulator\n",
|
||||
fuse->min_uV, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regulator_is_supported_voltage(drv->vdd_apc,
|
||||
fuse->max_uV,
|
||||
fuse->max_uV);
|
||||
if (!ret) {
|
||||
dev_err(drv->dev,
|
||||
"max uV: %d (fuse corner: %d) not supported by regulator\n",
|
||||
fuse->max_uV, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = cpr_check_vreg_constraints(drv->dev, drv->vdd_apc, fuse);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_dbg(drv->dev,
|
||||
"fuse corner %d: [%d %d %d] RO%hhu quot %d squot %d\n",
|
||||
|
|
@ -953,126 +803,6 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cpr_calculate_scaling(const char *quot_offset,
|
||||
struct cpr_drv *drv,
|
||||
const struct fuse_corner_data *fdata,
|
||||
const struct corner *corner)
|
||||
{
|
||||
u32 quot_diff = 0;
|
||||
unsigned long freq_diff;
|
||||
int scaling;
|
||||
const struct fuse_corner *fuse, *prev_fuse;
|
||||
int ret;
|
||||
|
||||
fuse = corner->fuse_corner;
|
||||
prev_fuse = fuse - 1;
|
||||
|
||||
if (quot_offset) {
|
||||
ret = nvmem_cell_read_variable_le_u32(drv->dev, quot_offset, "_diff);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
quot_diff *= fdata->quot_offset_scale;
|
||||
quot_diff += fdata->quot_offset_adjust;
|
||||
} else {
|
||||
quot_diff = fuse->quot - prev_fuse->quot;
|
||||
}
|
||||
|
||||
freq_diff = fuse->max_freq - prev_fuse->max_freq;
|
||||
freq_diff /= 1000000; /* Convert to MHz */
|
||||
scaling = 1000 * quot_diff / freq_diff;
|
||||
return min(scaling, fdata->max_quot_scale);
|
||||
}
|
||||
|
||||
static int cpr_interpolate(const struct corner *corner, int step_volt,
|
||||
const struct fuse_corner_data *fdata)
|
||||
{
|
||||
unsigned long f_high, f_low, f_diff;
|
||||
int uV_high, uV_low, uV;
|
||||
u64 temp, temp_limit;
|
||||
const struct fuse_corner *fuse, *prev_fuse;
|
||||
|
||||
fuse = corner->fuse_corner;
|
||||
prev_fuse = fuse - 1;
|
||||
|
||||
f_high = fuse->max_freq;
|
||||
f_low = prev_fuse->max_freq;
|
||||
uV_high = fuse->uV;
|
||||
uV_low = prev_fuse->uV;
|
||||
f_diff = fuse->max_freq - corner->freq;
|
||||
|
||||
/*
|
||||
* Don't interpolate in the wrong direction. This could happen
|
||||
* if the adjusted fuse voltage overlaps with the previous fuse's
|
||||
* adjusted voltage.
|
||||
*/
|
||||
if (f_high <= f_low || uV_high <= uV_low || f_high <= corner->freq)
|
||||
return corner->uV;
|
||||
|
||||
temp = f_diff * (uV_high - uV_low);
|
||||
temp = div64_ul(temp, f_high - f_low);
|
||||
|
||||
/*
|
||||
* max_volt_scale has units of uV/MHz while freq values
|
||||
* have units of Hz. Divide by 1000000 to convert to.
|
||||
*/
|
||||
temp_limit = f_diff * fdata->max_volt_scale;
|
||||
do_div(temp_limit, 1000000);
|
||||
|
||||
uV = uV_high - min(temp, temp_limit);
|
||||
return roundup(uV, step_volt);
|
||||
}
|
||||
|
||||
static unsigned int cpr_get_fuse_corner(struct dev_pm_opp *opp)
|
||||
{
|
||||
struct device_node *np;
|
||||
unsigned int fuse_corner = 0;
|
||||
|
||||
np = dev_pm_opp_get_of_node(opp);
|
||||
if (of_property_read_u32(np, "qcom,opp-fuse-level", &fuse_corner))
|
||||
pr_err("%s: missing 'qcom,opp-fuse-level' property\n",
|
||||
__func__);
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
return fuse_corner;
|
||||
}
|
||||
|
||||
static unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref,
|
||||
struct device *cpu_dev)
|
||||
{
|
||||
u64 rate = 0;
|
||||
struct device_node *ref_np;
|
||||
struct device_node *desc_np;
|
||||
struct device_node *child_np = NULL;
|
||||
struct device_node *child_req_np = NULL;
|
||||
|
||||
desc_np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
|
||||
if (!desc_np)
|
||||
return 0;
|
||||
|
||||
ref_np = dev_pm_opp_get_of_node(ref);
|
||||
if (!ref_np)
|
||||
goto out_ref;
|
||||
|
||||
do {
|
||||
of_node_put(child_req_np);
|
||||
child_np = of_get_next_available_child(desc_np, child_np);
|
||||
child_req_np = of_parse_phandle(child_np, "required-opps", 0);
|
||||
} while (child_np && child_req_np != ref_np);
|
||||
|
||||
if (child_np && child_req_np == ref_np)
|
||||
of_property_read_u64(child_np, "opp-hz", &rate);
|
||||
|
||||
of_node_put(child_req_np);
|
||||
of_node_put(child_np);
|
||||
of_node_put(ref_np);
|
||||
out_ref:
|
||||
of_node_put(desc_np);
|
||||
|
||||
return (unsigned long) rate;
|
||||
}
|
||||
|
||||
static int cpr_corner_init(struct cpr_drv *drv)
|
||||
{
|
||||
const struct cpr_desc *desc = drv->desc;
|
||||
|
|
@ -1110,7 +840,7 @@ static int cpr_corner_init(struct cpr_drv *drv)
|
|||
opp = dev_pm_opp_find_level_exact(&drv->pd.dev, level);
|
||||
if (IS_ERR(opp))
|
||||
return -EINVAL;
|
||||
fc = cpr_get_fuse_corner(opp);
|
||||
fc = cpr_get_fuse_corner(opp, 0);
|
||||
if (!fc) {
|
||||
dev_pm_opp_put(opp);
|
||||
return -EINVAL;
|
||||
|
|
@ -1186,7 +916,7 @@ static int cpr_corner_init(struct cpr_drv *drv)
|
|||
corner->uV = fuse->uV;
|
||||
|
||||
if (prev_fuse && cdata[i - 1].freq == prev_fuse->max_freq) {
|
||||
scaling = cpr_calculate_scaling(quot_offset, drv,
|
||||
scaling = cpr_calculate_scaling(quot_offset, drv->dev,
|
||||
fdata, corner);
|
||||
if (scaling < 0)
|
||||
return scaling;
|
||||
|
|
@ -1224,47 +954,6 @@ static int cpr_corner_init(struct cpr_drv *drv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct cpr_fuse *cpr_get_fuses(struct cpr_drv *drv)
|
||||
{
|
||||
const struct cpr_desc *desc = drv->desc;
|
||||
struct cpr_fuse *fuses;
|
||||
int i;
|
||||
|
||||
fuses = devm_kcalloc(drv->dev, desc->num_fuse_corners,
|
||||
sizeof(struct cpr_fuse),
|
||||
GFP_KERNEL);
|
||||
if (!fuses)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
for (i = 0; i < desc->num_fuse_corners; i++) {
|
||||
char tbuf[32];
|
||||
|
||||
snprintf(tbuf, 32, "cpr_ring_osc%d", i + 1);
|
||||
fuses[i].ring_osc = devm_kstrdup(drv->dev, tbuf, GFP_KERNEL);
|
||||
if (!fuses[i].ring_osc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
snprintf(tbuf, 32, "cpr_init_voltage%d", i + 1);
|
||||
fuses[i].init_voltage = devm_kstrdup(drv->dev, tbuf,
|
||||
GFP_KERNEL);
|
||||
if (!fuses[i].init_voltage)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
snprintf(tbuf, 32, "cpr_quotient%d", i + 1);
|
||||
fuses[i].quotient = devm_kstrdup(drv->dev, tbuf, GFP_KERNEL);
|
||||
if (!fuses[i].quotient)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
snprintf(tbuf, 32, "cpr_quotient_offset%d", i + 1);
|
||||
fuses[i].quotient_offset = devm_kstrdup(drv->dev, tbuf,
|
||||
GFP_KERNEL);
|
||||
if (!fuses[i].quotient_offset)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
return fuses;
|
||||
}
|
||||
|
||||
static void cpr_set_loop_allowed(struct cpr_drv *drv)
|
||||
{
|
||||
drv->loop_disabled = false;
|
||||
|
|
@ -1296,54 +985,6 @@ static int cpr_init_parameters(struct cpr_drv *drv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cpr_find_initial_corner(struct cpr_drv *drv)
|
||||
{
|
||||
unsigned long rate;
|
||||
const struct corner *end;
|
||||
struct corner *iter;
|
||||
unsigned int i = 0;
|
||||
|
||||
if (!drv->cpu_clk) {
|
||||
dev_err(drv->dev, "cannot get rate from NULL clk\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
end = &drv->corners[drv->num_corners - 1];
|
||||
rate = clk_get_rate(drv->cpu_clk);
|
||||
|
||||
/*
|
||||
* Some bootloaders set a CPU clock frequency that is not defined
|
||||
* in the OPP table. When running at an unlisted frequency,
|
||||
* cpufreq_online() will change to the OPP which has the lowest
|
||||
* frequency, at or above the unlisted frequency.
|
||||
* Since cpufreq_online() always "rounds up" in the case of an
|
||||
* unlisted frequency, this function always "rounds down" in case
|
||||
* of an unlisted frequency. That way, when cpufreq_online()
|
||||
* triggers the first ever call to cpr_set_performance_state(),
|
||||
* it will correctly determine the direction as UP.
|
||||
*/
|
||||
for (iter = drv->corners; iter <= end; iter++) {
|
||||
if (iter->freq > rate)
|
||||
break;
|
||||
i++;
|
||||
if (iter->freq == rate) {
|
||||
drv->corner = iter;
|
||||
break;
|
||||
}
|
||||
if (iter->freq < rate)
|
||||
drv->corner = iter;
|
||||
}
|
||||
|
||||
if (!drv->corner) {
|
||||
dev_err(drv->dev, "boot up corner not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(drv->dev, "boot up perf state: %u\n", i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct cpr_desc qcs404_cpr_desc = {
|
||||
.num_fuse_corners = 3,
|
||||
.min_diff_quot = CPR_FUSE_MIN_QUOT_DIFF,
|
||||
|
|
@ -1531,8 +1172,9 @@ static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
|
|||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
ret = cpr_find_initial_corner(drv);
|
||||
if (ret)
|
||||
ret = cpr_find_initial_corner(drv->dev, drv->cpu_clk, drv->corners,
|
||||
drv->num_corners);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
||||
if (acc_desc->config)
|
||||
|
|
@ -1616,6 +1258,7 @@ static int cpr_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct cpr_drv *drv;
|
||||
const struct cpr_desc *desc;
|
||||
int irq, ret;
|
||||
const struct cpr_acc_desc *data;
|
||||
struct device_node *np;
|
||||
|
|
@ -1631,6 +1274,7 @@ static int cpr_probe(struct platform_device *pdev)
|
|||
drv->dev = dev;
|
||||
drv->desc = data->cpr_desc;
|
||||
drv->acc_desc = data->acc_desc;
|
||||
desc = drv->desc;
|
||||
|
||||
drv->fuse_corners = devm_kcalloc(dev, drv->desc->num_fuse_corners,
|
||||
sizeof(*drv->fuse_corners),
|
||||
|
|
@ -1670,11 +1314,13 @@ static int cpr_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
drv->cpr_fuses = cpr_get_fuses(drv);
|
||||
drv->cpr_fuses = cpr_get_fuses(drv->dev, 0, desc->num_fuse_corners);
|
||||
if (IS_ERR(drv->cpr_fuses))
|
||||
return PTR_ERR(drv->cpr_fuses);
|
||||
|
||||
ret = cpr_populate_ring_osc_idx(drv);
|
||||
ret = cpr_populate_ring_osc_idx(drv->dev, drv->fuse_corners,
|
||||
drv->cpr_fuses,
|
||||
desc->num_fuse_corners);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
2897
drivers/soc/qcom/cpr3.c
Normal file
2897
drivers/soc/qcom/cpr3.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -190,10 +190,14 @@
|
|||
#define AGGRE2_SNOC_NORTH_AXI 181
|
||||
#define SSC_XO 182
|
||||
#define SSC_CNOC_AHBS_CLK 183
|
||||
#define HLOS1_VOTE_LPASS_CORE_SMMU_CLK 184
|
||||
#define HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 185
|
||||
|
||||
#define PCIE_0_GDSC 0
|
||||
#define UFS_GDSC 1
|
||||
#define USB_30_GDSC 2
|
||||
#define LPASS_ADSP_GDSC 3
|
||||
#define LPASS_CORE_GDSC 4
|
||||
|
||||
#define GCC_BLSP1_QUP1_BCR 0
|
||||
#define GCC_BLSP1_QUP2_BCR 1
|
||||
|
|
@ -304,5 +308,6 @@
|
|||
#define GCC_QUSB2PHY_PRIM_BCR 106
|
||||
#define GCC_QUSB2PHY_SEC_BCR 107
|
||||
#define GCC_MSS_RESTART 108
|
||||
#define GCC_MSS_Q6_BIMC_AXI_CLK 109
|
||||
|
||||
#endif
|
||||
|
|
|
|||
128
include/dt-bindings/interconnect/qcom,msm8998.h
Normal file
128
include/dt-bindings/interconnect/qcom,msm8998.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* MSM8998 interconnect IDs */
|
||||
|
||||
#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_MSM8998_H
|
||||
#define __DT_BINDINGS_INTERCONNECT_QCOM_MSM8998_H
|
||||
|
||||
/* A1NOC */
|
||||
#define MASTER_PCIE_0 0
|
||||
#define MASTER_USB3 1
|
||||
#define MASTER_UFS 2
|
||||
#define MASTER_BLSP_2 3
|
||||
#define SLAVE_A1NOC_SNOC 4
|
||||
|
||||
/* A2NOC */
|
||||
#define MASTER_IPA 0
|
||||
#define MASTER_CNOC_A2NOC 1
|
||||
#define MASTER_SDCC_2 2
|
||||
#define MASTER_SDCC_4 3
|
||||
#define MASTER_TSIF 4
|
||||
#define MASTER_BLSP_1 5
|
||||
#define MASTER_CRVIRT_A2NOC 6
|
||||
#define MASTER_CRYPTO_C0 7
|
||||
#define SLAVE_A2NOC_SNOC 8
|
||||
#define SLAVE_CRVIRT_A2NOC 9
|
||||
|
||||
/* BIMC */
|
||||
#define MASTER_GNOC_BIMC 0
|
||||
#define MASTER_OXILI 1
|
||||
#define MASTER_MNOC_BIMC 2
|
||||
#define MASTER_SNOC_BIMC 3
|
||||
#define SLAVE_EBI 4
|
||||
#define SLAVE_HMSS_L3 5
|
||||
#define SLAVE_BIMC_SNOC_0 6
|
||||
#define SLAVE_BIMC_SNOC_1 7
|
||||
|
||||
/* CNOC */
|
||||
#define MASTER_SNOC_CNOC 0
|
||||
#define MASTER_QDSS_DAP 1
|
||||
#define SLAVE_CNOC_A2NOC 2
|
||||
#define SLAVE_SSC_CFG 3
|
||||
#define SLAVE_MPM 4
|
||||
#define SLAVE_PMIC_ARB 5
|
||||
#define SLAVE_TLMM_NORTH 6
|
||||
#define SLAVE_PIMEM_CFG 7
|
||||
#define SLAVE_IMEM_CFG 8
|
||||
#define SLAVE_MESSAGE_RAM 9
|
||||
#define SLAVE_SKL 10
|
||||
#define SLAVE_BIMC_CFG 11
|
||||
#define SLAVE_PRNG 12
|
||||
#define SLAVE_A2NOC_CFG 13
|
||||
#define SLAVE_IPA 14
|
||||
#define SLAVE_TCSR 15
|
||||
#define SLAVE_SNOC_CFG 16
|
||||
#define SLAVE_CLK_CTL 17
|
||||
#define SLAVE_GLM 18
|
||||
#define SLAVE_SPDM 19
|
||||
#define SLAVE_GPUSS_CFG 20
|
||||
#define SLAVE_CNOC_MNOC_CFG 21
|
||||
#define SLAVE_QM_CFG 22
|
||||
#define SLAVE_MSS_CFG 23
|
||||
#define SLAVE_UFS_CFG 24
|
||||
#define SLAVE_TLMM_WEST 25
|
||||
#define SLAVE_A1NOC_CFG 26
|
||||
#define SLAVE_AHB2PHY 27
|
||||
#define SLAVE_BLSP_2 28
|
||||
#define SLAVE_PDM 29
|
||||
#define SLAVE_USB3_0 30
|
||||
#define SLAVE_A1NOC_SMMU_CFG 31
|
||||
#define SLAVE_BLSP_1 32
|
||||
#define SLAVE_SDCC_2 33
|
||||
#define SLAVE_SDCC_4 34
|
||||
#define SLAVE_TSIF 35
|
||||
#define SLAVE_QDSS_CFG 36
|
||||
#define SLAVE_TLMM_EAST 37
|
||||
#define SLAVE_CNOC_MNOC_MMSS_CFG 38
|
||||
#define SLAVE_SRVC_CNOC 39
|
||||
|
||||
/* GNOC */
|
||||
#define MASTER_APSS_PROC 0
|
||||
#define SLAVE_GNOC_BIMC 1
|
||||
|
||||
/* MNOC */
|
||||
#define MASTER_CNOC_MNOC_CFG 0
|
||||
#define MASTER_CPP 1
|
||||
#define MASTER_JPEG 2
|
||||
#define MASTER_MDP_P0 3
|
||||
#define MASTER_MDP_P1 4
|
||||
#define MASTER_ROTATOR 5
|
||||
#define MASTER_VENUS 6
|
||||
#define MASTER_VFE 7
|
||||
#define MASTER_VENUS_VMEM 8
|
||||
#define SLAVE_MNOC_BIMC 9
|
||||
#define SLAVE_VMEM 10
|
||||
#define SLAVE_SRVC_MNOC 11
|
||||
#define MASTER_CNOC_MNOC_MMSS_CFG 12
|
||||
#define SLAVE_CAMERA_CFG 13
|
||||
#define SLAVE_CAMERA_THROTTLE_CFG 14
|
||||
#define SLAVE_MISC_CFG 15
|
||||
#define SLAVE_VENUS_THROTTLE_CFG 16
|
||||
#define SLAVE_VENUS_CFG 17
|
||||
#define SLAVE_VMEM_CFG 18
|
||||
#define SLAVE_MMSS_CLK_XPU_CFG 19
|
||||
#define SLAVE_MMSS_CLK_CFG 20
|
||||
#define SLAVE_DISPLAY_CFG 21
|
||||
#define SLAVE_DISPLAY_THROTTLE_CFG 22
|
||||
#define SLAVE_SMMU_CFG 23
|
||||
|
||||
/* SNOC */
|
||||
#define MASTER_HMSS 0
|
||||
#define MASTER_QDSS_BAM 1
|
||||
#define MASTER_SNOC_CFG 2
|
||||
#define MASTER_BIMC_SNOC_0 3
|
||||
#define MASTER_BIMC_SNOC_1 4
|
||||
#define MASTER_A1NOC_SNOC 5
|
||||
#define MASTER_A2NOC_SNOC 6
|
||||
#define MASTER_QDSS_ETR 7
|
||||
#define SLAVE_HMSS 8
|
||||
#define SLAVE_LPASS 9
|
||||
#define SLAVE_WLAN 10
|
||||
#define SLAVE_SNOC_BIMC 11
|
||||
#define SLAVE_SNOC_CNOC 12
|
||||
#define SLAVE_IMEM 13
|
||||
#define SLAVE_PIMEM 14
|
||||
#define SLAVE_QDSS_STM 15
|
||||
#define SLAVE_PCIE_0 16
|
||||
#define SLAVE_SRVC_SNOC 17
|
||||
|
||||
#endif
|
||||
9
include/dt-bindings/sound/msm8998-lpass.h
Normal file
9
include/dt-bindings/sound/msm8998-lpass.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_MSM8998_LPASS_H
|
||||
#define __DT_MSM8998_LPASS_H
|
||||
|
||||
#include <dt-bindings/sound/qcom,lpass.h>
|
||||
|
||||
/* NOTE: Use qcom,lpass.h to define any AIF ID's for LPASS */
|
||||
|
||||
#endif /* __DT_MSM8998_LPASS_H */
|
||||
17
include/soc/qcom/cpr.h
Normal file
17
include/soc/qcom/cpr.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019 Linaro Limited
|
||||
* Copyright (c) 2021, AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
*/
|
||||
|
||||
#ifndef __CPR_H__
|
||||
#define __CPR_H__
|
||||
|
||||
struct cpr_ext_data {
|
||||
int mem_acc_threshold_uV;
|
||||
int apm_threshold_uV;
|
||||
};
|
||||
|
||||
#endif /* __CPR_H__ */
|
||||
|
|
@ -1661,7 +1661,7 @@ static int elf_validity_check(struct load_info *info)
|
|||
}
|
||||
|
||||
if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0) {
|
||||
pr_err("Invalid ELF header magic: != %s\n", ELFMAG);
|
||||
pr_debug("Invalid ELF header magic: != %s\n", ELFMAG);
|
||||
goto no_exec;
|
||||
}
|
||||
if (info->hdr->e_type != ET_REL) {
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ elif [ "${LOCALVERSION+set}" != "set" ]; then
|
|||
# If the variable LOCALVERSION is set (including being set
|
||||
# to an empty string), we don't want to append a plus sign.
|
||||
scm=$(scm_version --short)
|
||||
res="$res${scm:++}"
|
||||
#res="$res${scm:++}"
|
||||
fi
|
||||
|
||||
echo "$res"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <sound/jack.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slimbus.h>
|
||||
#include <sound/soc.h>
|
||||
|
|
@ -88,12 +89,18 @@
|
|||
#define WCD9335_DEC_PWR_LVL_HP 0x04
|
||||
#define WCD9335_DEC_PWR_LVL_DF 0x00
|
||||
|
||||
#define WCD9335_MBHC_MAX_BUTTONS (8)
|
||||
|
||||
#define WCD9335_SLIM_RX_CH(p) \
|
||||
{.port = p + WCD9335_RX_START, .shift = p,}
|
||||
|
||||
#define WCD9335_SLIM_TX_CH(p) \
|
||||
{.port = p, .shift = p,}
|
||||
|
||||
static int btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4;
|
||||
static int hs_jack_mask = SND_JACK_HEADPHONE | SND_JACK_HEADSET;
|
||||
|
||||
/* vout step value */
|
||||
#define WCD9335_CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25)
|
||||
|
||||
|
|
@ -310,6 +317,16 @@ struct wcd9335_codec {
|
|||
u32 num_rx_port;
|
||||
u32 num_tx_port;
|
||||
|
||||
struct snd_soc_jack *jack;
|
||||
bool hphl_jack_type_normally_open;
|
||||
bool gnd_jack_type_normally_open;
|
||||
bool mbhc_btn_enabled;
|
||||
int mbhc_btn0_released;
|
||||
bool detect_accessory_type;
|
||||
int accessory_type;
|
||||
/* Voltage threshold for button detection */
|
||||
u32 vref_btn[WCD9335_MBHC_MAX_BUTTONS];
|
||||
|
||||
int sido_input_src;
|
||||
enum wcd9335_sido_voltage sido_voltage;
|
||||
|
||||
|
|
@ -467,7 +484,7 @@ static const struct wcd9335_reg_mask_val wcd9335_codec_reg_init[] = {
|
|||
{WCD9335_RCO_CTRL_2, 0x0F, 0x08},
|
||||
{WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
|
||||
{WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
|
||||
{WCD9335_HPH_OCP_CTL, 0xFF, 0x5A},
|
||||
{WCD9335_HPH_OCP_CTL, 0xFF, 0x7A}, /*downstream is ff 7a */
|
||||
{WCD9335_HPH_L_TEST, 0x01, 0x01},
|
||||
{WCD9335_HPH_R_TEST, 0x01, 0x01},
|
||||
{WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
|
||||
|
|
@ -480,6 +497,13 @@ static const struct wcd9335_reg_mask_val wcd9335_codec_reg_init[] = {
|
|||
{WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
|
||||
{WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
|
||||
{WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
|
||||
|
||||
{WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xA0},
|
||||
{WCD9335_SE_LO_COM1, 0xFF, 0xC0},
|
||||
{WCD9335_CDC_RX3_RX_PATH_SEC0, 0xFC, 0xF4},
|
||||
{WCD9335_CDC_RX4_RX_PATH_SEC0, 0xFC, 0xF4},
|
||||
{WCD9335_CDC_RX5_RX_PATH_SEC0, 0xFC, 0xF8},
|
||||
{WCD9335_CDC_RX6_RX_PATH_SEC0, 0xFC, 0xF8},
|
||||
};
|
||||
|
||||
/* Cutoff frequency for high pass filter */
|
||||
|
|
@ -2805,7 +2829,6 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
|
|||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_component_update_bits(comp, hpf_gate_reg, 0x01, 0x00);
|
||||
|
||||
if (decimator == 0) {
|
||||
snd_soc_component_write(comp,
|
||||
WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
|
||||
|
|
@ -2816,7 +2839,6 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
|
|||
snd_soc_component_write(comp,
|
||||
WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
|
||||
}
|
||||
|
||||
snd_soc_component_update_bits(comp, hpf_gate_reg,
|
||||
0x01, 0x01);
|
||||
snd_soc_component_update_bits(comp, tx_vol_ctl_reg,
|
||||
|
|
@ -3729,11 +3751,12 @@ static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
|
||||
struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
|
||||
int hph_mode = wcd->hph_mode;
|
||||
|
||||
pr_err("%s\n", __func__);
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
pr_err("%s post pmu\n", __func__);
|
||||
/*
|
||||
* 7ms sleep is required after PA is enabled as per
|
||||
* HW requirement
|
||||
|
|
@ -3757,6 +3780,7 @@ static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
pr_err("%s pre pmd\n", __func__);
|
||||
wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
|
|
@ -3878,7 +3902,7 @@ static int wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
|
||||
struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
|
||||
int hph_mode = wcd->hph_mode;
|
||||
|
||||
pr_err("%s\n", __func__);
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
break;
|
||||
|
|
@ -3954,6 +3978,131 @@ static int wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t wcd9335_mbhc_sw_irq(int irq, void *data)
|
||||
{
|
||||
struct wcd9335_codec *wcd = data;
|
||||
struct snd_soc_component *component = wcd->component;
|
||||
bool ins = false;
|
||||
|
||||
if (snd_soc_component_read(component, WCD9335_ANA_MBHC_MECH) &
|
||||
WCD9335_MBHC_MECH_DETECT_TYPE_MASK)
|
||||
ins = true;
|
||||
|
||||
/* Set the detection type appropriately */
|
||||
snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH,
|
||||
WCD9335_MBHC_MECH_DETECT_TYPE_MASK,
|
||||
(!ins << WCD9335_MBHC_MECH_DETECT_TYPE_SHIFT));
|
||||
|
||||
if (ins) { /* hs insertion */
|
||||
u32 btndet_curr_src;
|
||||
|
||||
/*
|
||||
* If no micbias is enabled, then enable 100uA internal
|
||||
* current source for Button detection
|
||||
*/
|
||||
if (snd_soc_component_read(component, WCD9335_ANA_MICB2) &
|
||||
WCD9335_ANA_MICB2_ENABLE)
|
||||
btndet_curr_src = WCD9335_ANA_MBHC_BD_ISRC_OFF;
|
||||
else
|
||||
btndet_curr_src = WCD9335_ANA_MBHC_BD_ISRC_100UA;
|
||||
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9335_ANA_MBHC_ELECT,
|
||||
WCD9335_ANA_MBHC_BD_ISRC_CTL_MASK,
|
||||
btndet_curr_src);
|
||||
|
||||
/*
|
||||
* if only a btn0 press event is receive just before
|
||||
* insert event then its a 3 pole headphone else if
|
||||
* both press and release event received then its
|
||||
* a headset.
|
||||
*/
|
||||
if (wcd->mbhc_btn0_released) {
|
||||
snd_soc_jack_report(wcd->jack,
|
||||
SND_JACK_HEADSET, hs_jack_mask);
|
||||
wcd->accessory_type = SND_JACK_HEADSET;
|
||||
} else {
|
||||
snd_soc_jack_report(wcd->jack,
|
||||
SND_JACK_HEADPHONE, hs_jack_mask);
|
||||
wcd->accessory_type = SND_JACK_HEADPHONE;
|
||||
}
|
||||
|
||||
wcd->detect_accessory_type = false;
|
||||
|
||||
} else { /* removal */
|
||||
snd_soc_jack_report(wcd->jack, 0, hs_jack_mask);
|
||||
wcd->detect_accessory_type = true;
|
||||
wcd->mbhc_btn0_released = false;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t wcd9335_mbhc_btn_press_irq(int irq, void *data)
|
||||
{
|
||||
struct wcd9335_codec *wcd = data;
|
||||
struct snd_soc_component *comp = wcd->component;
|
||||
u32 btn_result, result;
|
||||
|
||||
/* do not handle any button events for headset without buttons */
|
||||
if (wcd->accessory_type == SND_JACK_HEADPHONE)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
result = snd_soc_component_read(comp, WCD9335_ANA_MBHC_RESULT_3);
|
||||
btn_result = result & WCD9335_MBHC_BTN_RESULT_MASK;
|
||||
|
||||
switch (btn_result) {
|
||||
case 0xf:
|
||||
snd_soc_jack_report(wcd->jack, SND_JACK_BTN_4, btn_mask);
|
||||
break;
|
||||
case 0x4:
|
||||
snd_soc_jack_report(wcd->jack, SND_JACK_BTN_4, btn_mask);
|
||||
break;
|
||||
case 0x3:
|
||||
snd_soc_jack_report(wcd->jack, SND_JACK_BTN_3, btn_mask);
|
||||
break;
|
||||
case 0x2:
|
||||
snd_soc_jack_report(wcd->jack, SND_JACK_BTN_2, btn_mask);
|
||||
break;
|
||||
case 0x1:
|
||||
snd_soc_jack_report(wcd->jack, SND_JACK_BTN_1, btn_mask);
|
||||
break;
|
||||
case 0x0:
|
||||
/* handle BTN_0 specially for type detection */
|
||||
if (!wcd->detect_accessory_type)
|
||||
snd_soc_jack_report(wcd->jack,
|
||||
SND_JACK_BTN_0, btn_mask);
|
||||
break;
|
||||
default:
|
||||
dev_err(comp->dev,
|
||||
"Unexpected button press result (%x)", btn_result);
|
||||
break;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t wcd9335_mbhc_bt_rel_irq(int irq, void *data)
|
||||
{
|
||||
struct wcd9335_codec *wcd = data;
|
||||
|
||||
|
||||
if (wcd->detect_accessory_type) {
|
||||
u32 result = snd_soc_component_read(wcd->component,
|
||||
WCD9335_ANA_MBHC_RESULT_3);
|
||||
|
||||
/* check if its BTN0 thats released */
|
||||
if (!(result & WCD9335_MBHC_BTN_RESULT_MASK))
|
||||
wcd->mbhc_btn0_released = true;
|
||||
|
||||
} else {
|
||||
if (wcd->accessory_type != SND_JACK_HEADPHONE)
|
||||
snd_soc_jack_report(wcd->jack, 0, btn_mask);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t wcd9335_slimbus_irq(int irq, void *data)
|
||||
{
|
||||
struct wcd9335_codec *wcd = data;
|
||||
|
|
@ -4028,11 +4177,95 @@ static irqreturn_t wcd9335_slimbus_irq(int irq, void *data)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void wcd9335_program_btn_threshold(struct wcd9335_codec *wcd)
|
||||
{
|
||||
int i, vth;
|
||||
|
||||
for (i = 0; i < WCD9335_MBHC_MAX_BUTTONS; i++) {
|
||||
vth = ((wcd->vref_btn[i] * 2) / 25) & 0x3F;
|
||||
snd_soc_component_update_bits(wcd->component,
|
||||
WCD9335_ANA_MBHC_BTN0 + i,
|
||||
0xFC, vth << 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd9335_mbhc_initialise(struct wcd9335_codec *wcd)
|
||||
{
|
||||
struct snd_soc_component *comp = wcd->component;
|
||||
u32 plug_type = 0;
|
||||
|
||||
snd_soc_component_update_bits(comp, WCD9335_MBHC_PLUG_DETECT_CTL,
|
||||
WCD9335_MBHC_HSDET_PULLUP_CTL_MASK,
|
||||
WCD9335_MBHC_HSDET_PULLUP_CTL_1_2P0_UA);
|
||||
|
||||
if (wcd->hphl_jack_type_normally_open)
|
||||
plug_type |= WCD9335_MBHC_HPHL_PLUG_TYPE_NO;
|
||||
|
||||
if (wcd->gnd_jack_type_normally_open)
|
||||
plug_type |= WCD9335_MBHC_GND_PLUG_TYPE_NO;
|
||||
|
||||
snd_soc_component_write(wcd->component, WCD9335_ANA_MBHC_MECH,
|
||||
plug_type |
|
||||
WCD9335_MBHC_L_DET_EN |
|
||||
WCD9335_MBHC_HSL_PULLUP_COMP_EN |
|
||||
WCD9335_MBHC_HPHL_100K_TO_GND_EN);
|
||||
|
||||
/* Insertion debounce set to 96ms */
|
||||
snd_soc_component_write(wcd->component,
|
||||
WCD9335_MBHC_PLUG_DETECT_CTL,
|
||||
WCD9335_MBHC_DBNC_TIMER_INSREM_DBNC_T_96_MS|
|
||||
WCD9335_MBHC_HSDET_PULLUP_CTL_1_2P0_UA);
|
||||
/* Button Debounce set to 16ms */
|
||||
snd_soc_component_update_bits(wcd->component, WCD9335_MBHC_CTL_1,
|
||||
WCD9335_MBHC_BTN_DBNC_MASK,
|
||||
WCD9335_MBHC_BTN_DBNC_T_16_MS);
|
||||
|
||||
/* enable bias distribution control */
|
||||
snd_soc_component_update_bits(comp, WCD9335_ANA_MBHC_ELECT,
|
||||
WCD9335_ANA_MBHC_BIAS_EN_MASK,
|
||||
WCD9335_ANA_MBHC_BIAS_EN);
|
||||
|
||||
snd_soc_component_update_bits(wcd->component,
|
||||
WCD9335_ANA_MBHC_ELECT,
|
||||
WCD9335_ANA_MBHC_BD_ISRC_CTL_MASK,
|
||||
WCD9335_ANA_MBHC_BD_ISRC_100UA);
|
||||
|
||||
/* enable MBHC clock */
|
||||
snd_soc_component_update_bits(wcd->component, WCD9335_MBHC_CTL_1,
|
||||
WCD9335_MBHC_CTL_RCO_EN_MASK,
|
||||
WCD9335_MBHC_CTL_RCO_EN);
|
||||
|
||||
snd_soc_component_update_bits(wcd->component, WCD9335_MBHC_CTL_2,
|
||||
WCD9335_MBHC_HS_VREF_CTL_MASK,
|
||||
WCD9335_MBHC_HS_VREF_1P5_V);
|
||||
|
||||
/* program HS_VREF value */
|
||||
wcd9335_program_btn_threshold(wcd);
|
||||
/* Start FSM */
|
||||
snd_soc_component_update_bits(wcd->component, WCD9335_ANA_MBHC_ELECT,
|
||||
BIT(7), BIT(7));
|
||||
|
||||
wcd->mbhc_btn0_released = false;
|
||||
wcd->detect_accessory_type = true;
|
||||
}
|
||||
|
||||
static struct wcd9335_irq wcd9335_irqs[] = {
|
||||
{
|
||||
.irq = WCD9335_IRQ_SLIMBUS,
|
||||
.handler = wcd9335_slimbus_irq,
|
||||
.name = "SLIM Slave",
|
||||
}, {
|
||||
.irq = WCD9335_IRQ_MBHC_SW_DET,
|
||||
.handler = wcd9335_mbhc_sw_irq,
|
||||
.name = "Headset Mech Insert Removal",
|
||||
}, {
|
||||
.irq = WCD9335_IRQ_MBHC_BUTTON_PRESS_DET,
|
||||
.handler = wcd9335_mbhc_btn_press_irq,
|
||||
.name = "Headset Button Press",
|
||||
}, {
|
||||
.irq = WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET,
|
||||
.handler = wcd9335_mbhc_bt_rel_irq,
|
||||
.name = "Headset Button Release",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -4841,6 +5074,7 @@ static void wcd9335_codec_init(struct snd_soc_component *component)
|
|||
wcd9335_codec_reg_init[i].val);
|
||||
|
||||
wcd9335_enable_efuse_sensing(component);
|
||||
wcd9335_mbhc_initialise(wcd);
|
||||
}
|
||||
|
||||
static int wcd9335_codec_probe(struct snd_soc_component *component)
|
||||
|
|
@ -4905,10 +5139,21 @@ static int wcd9335_codec_set_sysclk(struct snd_soc_component *comp,
|
|||
return clk_set_rate(wcd->mclk, freq);
|
||||
}
|
||||
|
||||
static int wcd9335_codec_set_jack(struct snd_soc_component *comp,
|
||||
struct snd_soc_jack *jack, void *data)
|
||||
{
|
||||
struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
|
||||
|
||||
wcd->jack = jack;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver wcd9335_component_drv = {
|
||||
.probe = wcd9335_codec_probe,
|
||||
.remove = wcd9335_codec_remove,
|
||||
.set_sysclk = wcd9335_codec_set_sysclk,
|
||||
.set_jack = wcd9335_codec_set_jack,
|
||||
.controls = wcd9335_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(wcd9335_snd_controls),
|
||||
.dapm_widgets = wcd9335_dapm_widgets,
|
||||
|
|
@ -4918,10 +5163,39 @@ static const struct snd_soc_component_driver wcd9335_component_drv = {
|
|||
.endianness = 1,
|
||||
};
|
||||
|
||||
static void of_parse_mbhc_data(struct device *dev, struct wcd9335_codec *wcd)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if (of_property_read_bool(dev->of_node,
|
||||
"qcom,hphl-jack-type-normally-open"))
|
||||
wcd->hphl_jack_type_normally_open = true;
|
||||
else
|
||||
wcd->hphl_jack_type_normally_open = false;
|
||||
|
||||
if (of_property_read_bool(dev->of_node,
|
||||
"qcom,gnd-jack-type-normally-open"))
|
||||
wcd->gnd_jack_type_normally_open = true;
|
||||
else
|
||||
wcd->gnd_jack_type_normally_open = false;
|
||||
|
||||
wcd->mbhc_btn_enabled = true;
|
||||
rval = of_property_read_u32_array(dev->of_node,
|
||||
"qcom,mbhc-vthreshold",
|
||||
&wcd->vref_btn[0],
|
||||
WCD9335_MBHC_MAX_BUTTONS);
|
||||
if (rval < 0) {
|
||||
wcd->mbhc_btn_enabled = false;
|
||||
dev_err(dev, "MBHC btn detection disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int wcd9335_probe(struct wcd9335_codec *wcd)
|
||||
{
|
||||
struct device *dev = wcd->dev;
|
||||
|
||||
of_parse_mbhc_data(dev, wcd);
|
||||
|
||||
memcpy(wcd->rx_chs, wcd9335_rx_chs, sizeof(wcd9335_rx_chs));
|
||||
memcpy(wcd->tx_chs, wcd9335_tx_chs, sizeof(wcd9335_tx_chs));
|
||||
|
||||
|
|
@ -5009,6 +5283,33 @@ static const struct regmap_irq wcd9335_codec_irqs[] = {
|
|||
.type_reg_mask = BIT(0),
|
||||
},
|
||||
},
|
||||
[WCD9335_IRQ_MBHC_SW_DET] = {
|
||||
.reg_offset = 1,
|
||||
.mask = BIT(0),
|
||||
.type = {
|
||||
.type_reg_offset = 1,
|
||||
.types_supported = IRQ_TYPE_EDGE_BOTH,
|
||||
.type_reg_mask = BIT(0),
|
||||
},
|
||||
},
|
||||
[WCD9335_IRQ_MBHC_BUTTON_PRESS_DET] = {
|
||||
.reg_offset = 1,
|
||||
.mask = BIT(2),
|
||||
.type = {
|
||||
.type_reg_offset = 1,
|
||||
.types_supported = IRQ_TYPE_EDGE_BOTH,
|
||||
.type_reg_mask = BIT(2),
|
||||
},
|
||||
},
|
||||
[WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET] = {
|
||||
.reg_offset = 1,
|
||||
.mask = BIT(3),
|
||||
.type = {
|
||||
.type_reg_offset = 1,
|
||||
.types_supported = IRQ_TYPE_EDGE_BOTH,
|
||||
.type_reg_mask = BIT(3),
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned int wcd9335_config_regs[] = {
|
||||
|
|
|
|||
|
|
@ -368,8 +368,10 @@
|
|||
#define WCD9335_EAR_CMBUFF WCD9335_REG(0x06, 0x0e2)
|
||||
#define WCD9335_DIFF_LO_LO2_COMPANDER WCD9335_REG(0x06, 0x0ea)
|
||||
#define WCD9335_DIFF_LO_LO1_COMPANDER WCD9335_REG(0x06, 0x0eb)
|
||||
#define WCD9335_DIFF_LO_CORE_OUT_PROG WCD9335_REG(0x06, 0x0ef)
|
||||
#define WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ WCD9335_REG(0x06, 0x0f1)
|
||||
#define WCD9335_DIFF_LO_COM_PA_FREQ WCD9335_REG(0x06, 0x0f2)
|
||||
#define WCD9335_SE_LO_COM1 WCD9335_REG(0x06, 0x0f6)
|
||||
#define WCD9335_SE_LO_LO3_GAIN WCD9335_REG(0x06, 0x0f8)
|
||||
#define WCD9335_SE_LO_LO3_CTRL WCD9335_REG(0x06, 0x0f9)
|
||||
#define WCD9335_SE_LO_LO4_GAIN WCD9335_REG(0x06, 0x0fa)
|
||||
|
|
@ -495,6 +497,7 @@
|
|||
#define WCD9335_CDC_RX3_RX_PATH_MIX_CTL WCD9335_REG(0x0b, 0x082)
|
||||
#define WCD9335_CDC_RX3_RX_PATH_MIX_CFG WCD9335_REG(0x0b, 0x083)
|
||||
#define WCD9335_CDC_RX3_RX_VOL_MIX_CTL WCD9335_REG(0x0b, 0x084)
|
||||
#define WCD9335_CDC_RX3_RX_PATH_SEC0 WCD9335_REG(0x0b, 0x085)
|
||||
#define WCD9335_CDC_RX4_RX_PATH_CTL WCD9335_REG(0x0b, 0x091)
|
||||
#define WCD9335_CDC_RX4_RX_PATH_CFG0 WCD9335_REG(0x0b, 0x092)
|
||||
#define WCD9335_CDC_RX4_RX_PATH_CFG2 WCD9335_REG(0x0b, 0x094)
|
||||
|
|
@ -502,6 +505,7 @@
|
|||
#define WCD9335_CDC_RX4_RX_PATH_MIX_CTL WCD9335_REG(0x0b, 0x096)
|
||||
#define WCD9335_CDC_RX4_RX_PATH_MIX_CFG WCD9335_REG(0x0b, 0x097)
|
||||
#define WCD9335_CDC_RX4_RX_VOL_MIX_CTL WCD9335_REG(0x0b, 0x098)
|
||||
#define WCD9335_CDC_RX4_RX_PATH_SEC0 WCD9335_REG(0x0b, 0x099)
|
||||
#define WCD9335_CDC_RX5_RX_PATH_CTL WCD9335_REG(0x0b, 0x0a5)
|
||||
#define WCD9335_CDC_RX5_RX_PATH_CFG0 WCD9335_REG(0x0b, 0x0a6)
|
||||
#define WCD9335_CDC_RX5_RX_PATH_CFG2 WCD9335_REG(0x0b, 0x0a8)
|
||||
|
|
@ -509,6 +513,7 @@
|
|||
#define WCD9335_CDC_RX5_RX_PATH_MIX_CTL WCD9335_REG(0x0b, 0x0aa)
|
||||
#define WCD9335_CDC_RX5_RX_PATH_MIX_CFG WCD9335_REG(0x0b, 0x0ab)
|
||||
#define WCD9335_CDC_RX5_RX_VOL_MIX_CTL WCD9335_REG(0x0b, 0x0ac)
|
||||
#define WCD9335_CDC_RX5_RX_PATH_SEC0 WCD9335_REG(0x0b, 0x0ad)
|
||||
#define WCD9335_CDC_RX6_RX_PATH_CTL WCD9335_REG(0x0b, 0x0b9)
|
||||
#define WCD9335_CDC_RX6_RX_PATH_CFG0 WCD9335_REG(0x0b, 0x0ba)
|
||||
#define WCD9335_CDC_RX6_RX_PATH_CFG2 WCD9335_REG(0x0b, 0x0bc)
|
||||
|
|
@ -516,6 +521,7 @@
|
|||
#define WCD9335_CDC_RX6_RX_PATH_MIX_CTL WCD9335_REG(0x0b, 0x0be)
|
||||
#define WCD9335_CDC_RX6_RX_PATH_MIX_CFG WCD9335_REG(0x0b, 0x0bf)
|
||||
#define WCD9335_CDC_RX6_RX_VOL_MIX_CTL WCD9335_REG(0x0b, 0x0c0)
|
||||
#define WCD9335_CDC_RX6_RX_PATH_SEC0 WCD9335_REG(0x0b, 0x0c1)
|
||||
#define WCD9335_CDC_RX7_RX_PATH_CTL WCD9335_REG(0x0b, 0x0cd)
|
||||
#define WCD9335_CDC_RX7_RX_PATH_CFG0 WCD9335_REG(0x0b, 0x0ce)
|
||||
#define WCD9335_CDC_RX7_RX_PATH_CFG1 WCD9335_REG(0x0b, 0x0cf)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ config SND_SOC_LPASS_APQ8016
|
|||
select SND_SOC_LPASS_CPU
|
||||
select SND_SOC_LPASS_PLATFORM
|
||||
|
||||
config SND_SOC_LPASS_MSM8998
|
||||
tristate
|
||||
select SND_SOC_LPASS_CPU
|
||||
select SND_SOC_LPASS_PLATFORM
|
||||
select SND_SOC_LPASS_HDMI
|
||||
|
||||
config SND_SOC_LPASS_SC7180
|
||||
tristate
|
||||
select SND_SOC_LPASS_CPU
|
||||
|
|
@ -148,6 +154,18 @@ config SND_SOC_MSM8996
|
|||
APQ8096 SoC-based systems.
|
||||
Say Y if you want to use audio device on this SoCs
|
||||
|
||||
config SND_SOC_MSM8998
|
||||
tristate "SoC Machine driver for MSM8998 and APQ8098 boards"
|
||||
depends on QCOM_APR && I2C && SOUNDWIRE
|
||||
depends on COMMON_CLK
|
||||
select SND_SOC_QDSP6
|
||||
select SND_SOC_QCOM_COMMON
|
||||
select SND_SOC_LPASS_MSM8998
|
||||
help
|
||||
To add support for audio on Qualcomm Technologies Inc.
|
||||
MSM8998 SoC-based systems.
|
||||
Say Y if you want to use audio device on this SoCs.
|
||||
|
||||
config SND_SOC_SDM845
|
||||
tristate "SoC Machine driver for SDM845 boards"
|
||||
depends on QCOM_APR && I2C && SOUNDWIRE
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ snd-soc-lpass-hdmi-objs := lpass-hdmi.o
|
|||
snd-soc-lpass-platform-objs := lpass-platform.o
|
||||
snd-soc-lpass-ipq806x-objs := lpass-ipq806x.o
|
||||
snd-soc-lpass-apq8016-objs := lpass-apq8016.o
|
||||
snd-soc-lpass-msm8998-objs := lpass-msm8998.o
|
||||
snd-soc-lpass-sc7180-objs := lpass-sc7180.o
|
||||
snd-soc-lpass-sc7280-objs := lpass-sc7280.o
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ obj-$(CONFIG_SND_SOC_LPASS_HDMI) += snd-soc-lpass-hdmi.o
|
|||
obj-$(CONFIG_SND_SOC_LPASS_PLATFORM) += snd-soc-lpass-platform.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_IPQ806X) += snd-soc-lpass-ipq806x.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += snd-soc-lpass-apq8016.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_MSM8998) += snd-soc-lpass-msm8998.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_SC7180) += snd-soc-lpass-sc7180.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_SC7280) += snd-soc-lpass-sc7280.o
|
||||
|
||||
|
|
@ -22,6 +24,7 @@ obj-$(CONFIG_SND_SOC_LPASS_SC7280) += snd-soc-lpass-sc7280.o
|
|||
snd-soc-storm-objs := storm.o
|
||||
snd-soc-apq8016-sbc-objs := apq8016_sbc.o
|
||||
snd-soc-apq8096-objs := apq8096.o
|
||||
snd-soc-msm8998-objs := msm8998.o
|
||||
snd-soc-sc7180-objs := sc7180.o
|
||||
snd-soc-sc7280-objs := sc7280.o
|
||||
snd-soc-sdm845-objs := sdm845.o
|
||||
|
|
@ -32,6 +35,7 @@ snd-soc-qcom-common-objs := common.o
|
|||
obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
|
||||
obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o
|
||||
obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-apq8096.o
|
||||
obj-$(CONFIG_SND_SOC_MSM8998) += snd-soc-msm8998.o
|
||||
obj-$(CONFIG_SND_SOC_SC7180) += snd-soc-sc7180.o
|
||||
obj-$(CONFIG_SND_SOC_SC7280) += snd-soc-sc7280.o
|
||||
obj-$(CONFIG_SND_SOC_SC8280XP) += snd-soc-sc8280xp.o
|
||||
|
|
|
|||
330
sound/soc/qcom/lpass-msm8998.c
Normal file
330
sound/soc/qcom/lpass-msm8998.c
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021 AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
*
|
||||
* lpass-msm8998.c -- ALSA SoC platform-machine driver for QTi LPASS
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <dt-bindings/sound/msm8998-lpass.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "lpass-lpaif-reg.h"
|
||||
#include "lpass.h"
|
||||
|
||||
static struct snd_soc_dai_driver msm8998_lpass_cpu_dai_driver[] = {
|
||||
{
|
||||
.id = MI2S_PRIMARY,
|
||||
.name = "Primary MI2S",
|
||||
.playback = {
|
||||
.stream_name = "Primary Playback",
|
||||
.formats = SNDRV_PCM_FMTBIT_S16,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.rate_min = 48000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "Primary Capture",
|
||||
.formats = SNDRV_PCM_FMTBIT_S16 |
|
||||
SNDRV_PCM_FMTBIT_S32,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.rate_min = 48000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
},
|
||||
.probe = &asoc_qcom_lpass_cpu_dai_probe,
|
||||
.ops = &asoc_qcom_lpass_cpu_dai_ops,
|
||||
}, {
|
||||
.id = MI2S_SECONDARY,
|
||||
.name = "Secondary MI2S",
|
||||
.playback = {
|
||||
.stream_name = "Secondary Playback",
|
||||
.formats = SNDRV_PCM_FMTBIT_S16,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.rate_min = 48000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
},
|
||||
.probe = &asoc_qcom_lpass_cpu_dai_probe,
|
||||
.ops = &asoc_qcom_lpass_cpu_dai_ops,
|
||||
}, {
|
||||
.id = MI2S_TERTIARY,
|
||||
.name = "Tertiary MI2S",
|
||||
.playback = {
|
||||
.stream_name = "Tertiary Playback",
|
||||
.formats = SNDRV_PCM_FMTBIT_S16,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.rate_min = 48000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
},
|
||||
.probe = &asoc_qcom_lpass_cpu_dai_probe,
|
||||
.ops = &asoc_qcom_lpass_cpu_dai_ops,
|
||||
}, {
|
||||
.id = MI2S_QUATERNARY,
|
||||
.name = "Quaternary MI2S",
|
||||
.playback = {
|
||||
.stream_name = "Quaternary Playback",
|
||||
.formats = SNDRV_PCM_FMTBIT_S16,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.rate_min = 48000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
},
|
||||
.probe = &asoc_qcom_lpass_cpu_dai_probe,
|
||||
.ops = &asoc_qcom_lpass_cpu_dai_ops,
|
||||
}, {
|
||||
.id = LPASS_DP_RX,
|
||||
.name = "Hdmi",
|
||||
.playback = {
|
||||
.stream_name = "Hdmi Playback",
|
||||
.formats = SNDRV_PCM_FMTBIT_S24,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.rate_min = 48000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
},
|
||||
.ops = &asoc_qcom_lpass_hdmi_dai_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static int msm8998_lpass_alloc_dma_channel(struct lpass_data *drvdata,
|
||||
int direction, unsigned int dai_id)
|
||||
{
|
||||
struct lpass_variant *v = drvdata->variant;
|
||||
int chan = 0;
|
||||
|
||||
if (dai_id == LPASS_DP_RX) {
|
||||
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
chan = find_first_zero_bit(&drvdata->hdmi_dma_ch_bit_map,
|
||||
v->hdmi_rdma_channels);
|
||||
|
||||
if (chan >= v->hdmi_rdma_channels)
|
||||
return -EBUSY;
|
||||
}
|
||||
set_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
|
||||
} else {
|
||||
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
chan = find_first_zero_bit(&drvdata->dma_ch_bit_map,
|
||||
v->rdma_channels);
|
||||
|
||||
if (chan >= v->rdma_channels)
|
||||
return -EBUSY;
|
||||
} else {
|
||||
chan = find_next_zero_bit(&drvdata->dma_ch_bit_map,
|
||||
v->wrdma_channel_start +
|
||||
v->wrdma_channels,
|
||||
v->wrdma_channel_start);
|
||||
|
||||
if (chan >= v->wrdma_channel_start + v->wrdma_channels)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
set_bit(chan, &drvdata->dma_ch_bit_map);
|
||||
}
|
||||
return chan;
|
||||
}
|
||||
|
||||
static int msm8998_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, unsigned int dai_id)
|
||||
{
|
||||
if (dai_id == LPASS_DP_RX)
|
||||
clear_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
|
||||
else
|
||||
clear_bit(chan, &drvdata->dma_ch_bit_map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm8998_lpass_init(struct platform_device *pdev)
|
||||
{
|
||||
struct lpass_data *drvdata = platform_get_drvdata(pdev);
|
||||
struct lpass_variant *variant = drvdata->variant;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret, i;
|
||||
|
||||
drvdata->clks = devm_kcalloc(dev, variant->num_clks,
|
||||
sizeof(*drvdata->clks), GFP_KERNEL);
|
||||
drvdata->num_clks = variant->num_clks;
|
||||
|
||||
for (i = 0; i < drvdata->num_clks; i++)
|
||||
drvdata->clks[i].id = variant->clk_name[i];
|
||||
|
||||
ret = devm_clk_bulk_get(dev, drvdata->num_clks, drvdata->clks);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get clocks %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
|
||||
if (ret) {
|
||||
dev_err(dev, "msm8998 clk_enable failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm8998_lpass_exit(struct platform_device *pdev)
|
||||
{
|
||||
struct lpass_data *drvdata = platform_get_drvdata(pdev);
|
||||
|
||||
clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct lpass_variant msm8998_data = {
|
||||
.i2sctrl_reg_base = 0x1000,
|
||||
.i2sctrl_reg_stride = 0x1000,
|
||||
.i2s_ports = 3,
|
||||
.irq_reg_base = 0xa000,
|
||||
.irq_reg_stride = 0x1000,
|
||||
.irq_ports = 3,
|
||||
.rdma_reg_base = 0xD000,
|
||||
.rdma_reg_stride = 0x1000,
|
||||
.rdma_channels = 5,
|
||||
.hdmi_rdma_reg_base = 0x3000,
|
||||
.hdmi_rdma_reg_stride = 0x1000,
|
||||
.hdmi_rdma_channels = 4,
|
||||
.dmactl_audif_start = 1, /* what's that?? */
|
||||
.wrdma_reg_base = 0x13000,
|
||||
.wrdma_reg_stride = 0x1000,
|
||||
.wrdma_channel_start = 5, /* ?? what's that ?? */
|
||||
.wrdma_channels = 4,
|
||||
|
||||
.loopback = REG_FIELD_ID(0x1000, 15, 15, 4, 0x1000),
|
||||
.spken = REG_FIELD_ID(0x1000, 14, 14, 4, 0x1000),
|
||||
.spkmode = REG_FIELD_ID(0x1000, 10, 13, 4, 0x1000),
|
||||
.spkmono = REG_FIELD_ID(0x1000, 9, 9, 4, 0x1000),
|
||||
.micen = REG_FIELD_ID(0x1000, 8, 8, 4, 0x1000),
|
||||
.micmode = REG_FIELD_ID(0x1000, 4, 7, 4, 0x1000),
|
||||
.micmono = REG_FIELD_ID(0x1000, 3, 3, 4, 0x1000),
|
||||
.wssrc = REG_FIELD_ID(0x1000, 2, 2, 4, 0x1000),
|
||||
.bitwidth = REG_FIELD_ID(0x1000, 0, 1, 4, 0x1000),
|
||||
|
||||
.rdma_dyncclk = REG_FIELD_ID(0xD000, 14, 14, 4, 0x1000),
|
||||
.rdma_bursten = REG_FIELD_ID(0xD000, 13, 13, 4, 0x1000),
|
||||
.rdma_wpscnt = REG_FIELD_ID(0xD000, 10, 12, 4, 0x1000),
|
||||
.rdma_intf = REG_FIELD_ID(0xD000, 6, 9, 4, 0x1000),
|
||||
.rdma_fifowm = REG_FIELD_ID(0xD000, 1, 5, 4, 0x1000),
|
||||
.rdma_enable = REG_FIELD_ID(0xD000, 0, 0, 4, 0x1000),
|
||||
|
||||
.wrdma_dyncclk = REG_FIELD_ID(0x13000, 12, 12, 3, 0x1000),
|
||||
.wrdma_bursten = REG_FIELD_ID(0x13000, 11, 11, 3, 0x1000),
|
||||
.wrdma_wpscnt = REG_FIELD_ID(0x13000, 8, 10, 3, 0x1000),
|
||||
.wrdma_intf = REG_FIELD_ID(0x13000, 4, 7, 3, 0x1000),
|
||||
.wrdma_fifowm = REG_FIELD_ID(0x13000, 1, 3, 3, 0x1000),
|
||||
.wrdma_enable = REG_FIELD_ID(0x13000, 0, 0, 3, 0x1000),
|
||||
|
||||
.hdmi_tx_ctl_addr = 0x1000,
|
||||
.hdmi_legacy_addr = 0x1008,
|
||||
.hdmi_vbit_addr = 0xc0,
|
||||
.hdmi_ch_lsb_addr = 0x48,
|
||||
.hdmi_ch_msb_addr = 0x4c,
|
||||
.ch_stride = 0x8,
|
||||
.hdmi_parity_addr = 0x34,
|
||||
.hdmi_dmactl_addr = 0x38,
|
||||
.hdmi_dma_stride = 0x4,
|
||||
.hdmi_DP_addr = 0xc8,
|
||||
.hdmi_sstream_addr = 0x1c,
|
||||
.hdmi_irq_reg_base = 0x63000,
|
||||
.hdmi_irq_ports = 1,
|
||||
|
||||
.hdmi_rdma_dyncclk = REG_FIELD_ID(0x3000, 14, 14, 3, 0x1000),
|
||||
.hdmi_rdma_bursten = REG_FIELD_ID(0x3000, 13, 13, 3, 0x1000),
|
||||
.hdmi_rdma_burst8 = REG_FIELD_ID(0x3000, 15, 15, 3, 0x1000),
|
||||
.hdmi_rdma_burst16 = REG_FIELD_ID(0x3000, 16, 16, 3, 0x1000),
|
||||
.hdmi_rdma_dynburst = REG_FIELD_ID(0x3000, 18, 18, 3, 0x1000),
|
||||
.hdmi_rdma_wpscnt = REG_FIELD_ID(0x3000, 10, 12, 3, 0x1000),
|
||||
.hdmi_rdma_fifowm = REG_FIELD_ID(0x3000, 1, 5, 3, 0x1000),
|
||||
.hdmi_rdma_enable = REG_FIELD_ID(0x3000, 0, 0, 3, 0x1000),
|
||||
|
||||
.sstream_en = REG_FIELD(0x1c, 0, 0),
|
||||
.dma_sel = REG_FIELD(0x1c, 1, 2),
|
||||
.auto_bbit_en = REG_FIELD(0x1c, 3, 3),
|
||||
.layout = REG_FIELD(0x1c, 4, 4),
|
||||
.layout_sp = REG_FIELD(0x1c, 5, 8),
|
||||
.set_sp_on_en = REG_FIELD(0x1c, 10, 10),
|
||||
.dp_audio = REG_FIELD(0x1c, 11, 11),
|
||||
.dp_staffing_en = REG_FIELD(0x1c, 12, 12),
|
||||
.dp_sp_b_hw_en = REG_FIELD(0x1c, 13, 13),
|
||||
|
||||
.mute = REG_FIELD(0xc8, 0, 0),
|
||||
.as_sdp_cc = REG_FIELD(0xc8, 1, 3),
|
||||
.as_sdp_ct = REG_FIELD(0xc8, 4, 7),
|
||||
.aif_db4 = REG_FIELD(0xc8, 8, 15),
|
||||
|
||||
.soft_reset = REG_FIELD(0x1000, 31, 31),
|
||||
.force_reset = REG_FIELD(0x1000, 30, 30),
|
||||
|
||||
.use_hw_chs = REG_FIELD(0x38, 0, 0),
|
||||
.use_hw_usr = REG_FIELD(0x38, 1, 1),
|
||||
.hw_chs_sel = REG_FIELD(0x38, 2, 4),
|
||||
.hw_usr_sel = REG_FIELD(0x38, 5, 6),
|
||||
|
||||
.replace_vbit = REG_FIELD(0xc0, 0, 0),
|
||||
.vbit_stream = REG_FIELD(0xc0, 1, 1),
|
||||
|
||||
.legacy_en = REG_FIELD(0x1008, 0, 0),
|
||||
.calc_en = REG_FIELD(0x34, 0, 0),
|
||||
.lsb_bits = REG_FIELD(0x48, 0, 31),
|
||||
.msb_bits = REG_FIELD(0x4c, 0, 16),
|
||||
|
||||
|
||||
.clk_name = (const char*[]) {
|
||||
"pcnoc-sway-clk",
|
||||
"audio-core",
|
||||
"pcnoc-mport-clk",
|
||||
},
|
||||
.num_clks = 3,
|
||||
.dai_driver = msm8998_lpass_cpu_dai_driver,
|
||||
.num_dai = ARRAY_SIZE(msm8998_lpass_cpu_dai_driver),
|
||||
.dai_osr_clk_names = (const char *[]) {
|
||||
"mclk0",
|
||||
"null",
|
||||
},
|
||||
.dai_bit_clk_names = (const char *[]) {
|
||||
"mi2s-bit-clk0",
|
||||
"mi2s-bit-clk1",
|
||||
},
|
||||
.init = msm8998_lpass_init,
|
||||
.exit = msm8998_lpass_exit,
|
||||
.alloc_dma_channel = msm8998_lpass_alloc_dma_channel,
|
||||
.free_dma_channel = msm8998_lpass_free_dma_channel,
|
||||
};
|
||||
|
||||
static const struct of_device_id msm8998_lpass_cpu_device_id[] __maybe_unused = {
|
||||
{.compatible = "qcom,msm8998-lpass-cpu", .data = &msm8998_data},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, msm8998_lpass_cpu_device_id);
|
||||
|
||||
static struct platform_driver msm8998_lpass_cpu_platform_driver = {
|
||||
.driver = {
|
||||
.name = "msm8998-lpass-cpu",
|
||||
.of_match_table = of_match_ptr(msm8998_lpass_cpu_device_id),
|
||||
},
|
||||
.probe = asoc_qcom_lpass_cpu_platform_probe,
|
||||
.remove = asoc_qcom_lpass_cpu_platform_remove,
|
||||
.shutdown = asoc_qcom_lpass_cpu_platform_shutdown,
|
||||
};
|
||||
|
||||
module_platform_driver(msm8998_lpass_cpu_platform_driver);
|
||||
|
||||
MODULE_DESCRIPTION("msm8998 LPASS CPU DRIVER");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
501
sound/soc/qcom/msm8998.c
Normal file
501
sound/soc/qcom/msm8998.c
Normal file
|
|
@ -0,0 +1,501 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Based on sdm845.c
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* MSM8998 ASoC driver
|
||||
* Copyright (c) 2021, AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/jack.h>
|
||||
#include <sound/soc.h>
|
||||
#include <linux/soundwire/sdw.h>
|
||||
#include <uapi/linux/input-event-codes.h>
|
||||
#include "common.h"
|
||||
#include "qdsp6/q6afe.h"
|
||||
|
||||
#define DRIVER_NAME "msm8998"
|
||||
#define DEFAULT_SAMPLE_RATE_48K 48000
|
||||
#define DEFAULT_MCLK_RATE 24576000
|
||||
#define TDM_BCLK_RATE 6144000
|
||||
#define MI2S_BCLK_RATE 1536000
|
||||
#define LEFT_SPK_TDM_TX_MASK 0x30
|
||||
#define RIGHT_SPK_TDM_TX_MASK 0xC0
|
||||
#define SPK_TDM_RX_MASK 0x03
|
||||
#define NUM_TDM_SLOTS 8
|
||||
#define SLIM_MAX_TX_PORTS 17
|
||||
#define SLIM_MAX_RX_PORTS 14
|
||||
#define WCD934X_DEFAULT_MCLK_RATE 9600000
|
||||
|
||||
struct msm8998_snd_data {
|
||||
struct snd_soc_jack jack;
|
||||
bool jack_setup;
|
||||
bool stream_prepared[SLIM_MAX_RX_PORTS];
|
||||
struct snd_soc_card *card;
|
||||
uint32_t quat_tdm_clk_count;
|
||||
struct sdw_stream_runtime *sruntime[SLIM_MAX_RX_PORTS];
|
||||
};
|
||||
|
||||
static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
|
||||
|
||||
static int msm8998_slim_snd_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct msm8998_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
|
||||
u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
|
||||
struct sdw_stream_runtime *sruntime;
|
||||
u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
|
||||
int ret = 0, i;
|
||||
|
||||
for_each_rtd_codec_dais(rtd, i, codec_dai) {
|
||||
sruntime = snd_soc_dai_get_stream(codec_dai,
|
||||
substream->stream);
|
||||
if (sruntime != ERR_PTR(-ENOTSUPP))
|
||||
pdata->sruntime[cpu_dai->id] = sruntime;
|
||||
|
||||
ret = snd_soc_dai_get_channel_map(codec_dai,
|
||||
&tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
|
||||
|
||||
if (ret != 0 && ret != -ENOTSUPP) {
|
||||
pr_err("failed to get codec chan map, err:%d\n", ret);
|
||||
return ret;
|
||||
} else if (ret == -ENOTSUPP) {
|
||||
/* Ignore unsupported */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
|
||||
rx_ch_cnt, rx_ch);
|
||||
else
|
||||
ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt,
|
||||
tx_ch, 0, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm8998_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
struct snd_soc_dai *codec_dai;
|
||||
int ret = 0, j;
|
||||
int channels, slot_width;
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
slot_width = 16;
|
||||
break;
|
||||
default:
|
||||
dev_err(rtd->dev, "%s: invalid param format 0x%x\n",
|
||||
__func__, params_format(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
channels = params_channels(params);
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x3,
|
||||
8, slot_width);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
|
||||
__func__, ret);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
|
||||
channels, tdm_slot_offset);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
|
||||
__func__, ret);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0,
|
||||
8, slot_width);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
|
||||
__func__, ret);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
|
||||
tdm_slot_offset, 0, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
|
||||
__func__, ret);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
for_each_rtd_codec_dais(rtd, j, codec_dai) {
|
||||
|
||||
if (!strcmp(codec_dai->component->name_prefix, "Left")) {
|
||||
ret = snd_soc_dai_set_tdm_slot(
|
||||
codec_dai, LEFT_SPK_TDM_TX_MASK,
|
||||
SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
|
||||
slot_width);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev,
|
||||
"DEV0 TDM slot err:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(codec_dai->component->name_prefix, "Right")) {
|
||||
ret = snd_soc_dai_set_tdm_slot(
|
||||
codec_dai, RIGHT_SPK_TDM_TX_MASK,
|
||||
SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
|
||||
slot_width);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev,
|
||||
"DEV1 TDM slot err:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm8998_snd_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int ret = 0;
|
||||
|
||||
switch (cpu_dai->id) {
|
||||
case QUATERNARY_TDM_RX_0:
|
||||
case QUATERNARY_TDM_TX_0:
|
||||
ret = msm8998_tdm_snd_hw_params(substream, params);
|
||||
break;
|
||||
case SLIMBUS_0_RX...SLIMBUS_6_TX:
|
||||
ret = msm8998_slim_snd_hw_params(substream, params);
|
||||
break;
|
||||
case QUATERNARY_MI2S_RX:
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm8998_dai_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
struct msm8998_snd_data *pdata = snd_soc_card_get_drvdata(card);
|
||||
struct snd_jack *jack;
|
||||
/*
|
||||
* Codec SLIMBUS configuration
|
||||
* RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13, RX14
|
||||
* TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13, TX14,
|
||||
* TX15, TX16
|
||||
*/
|
||||
unsigned int rx_ch[SLIM_MAX_RX_PORTS] = {144, 145, 146, 147, 148, 149,
|
||||
150, 151, 152, 153, 154, 155,
|
||||
156, 157 };
|
||||
unsigned int tx_ch[SLIM_MAX_TX_PORTS] = {128, 129, 130, 131, 132, 133,
|
||||
134, 135, 136, 137, 138, 139,
|
||||
140, 141, 142, 143};
|
||||
int ret, i;
|
||||
|
||||
if (!pdata->jack_setup) {
|
||||
ret = snd_soc_card_jack_new(card, "Headset Jack",
|
||||
SND_JACK_HEADSET |
|
||||
SND_JACK_HEADPHONE |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
&pdata->jack);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(card->dev, "Unable to add Headphone Jack\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
jack = pdata->jack.jack;
|
||||
|
||||
snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
|
||||
snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
|
||||
snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
|
||||
snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
|
||||
pdata->jack_setup = true;
|
||||
}
|
||||
|
||||
switch (cpu_dai->id) {
|
||||
case SLIMBUS_0_RX...SLIMBUS_6_TX:
|
||||
for_each_rtd_codec_dais(rtd, i, codec_dai) {
|
||||
ret = snd_soc_dai_set_channel_map(codec_dai,
|
||||
ARRAY_SIZE(tx_ch), tx_ch,
|
||||
ARRAY_SIZE(rx_ch), rx_ch);
|
||||
if (ret != 0 && ret != -ENOTSUPP)
|
||||
return ret;
|
||||
|
||||
snd_soc_dai_set_sysclk(codec_dai, 0,
|
||||
WCD934X_DEFAULT_MCLK_RATE,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
|
||||
ret = snd_soc_component_set_jack(codec_dai->component,
|
||||
&pdata->jack, NULL);
|
||||
if (ret != 0 && ret != -ENOTSUPP) {
|
||||
dev_warn(card->dev, "Failed to set jack: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm8998_snd_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct msm8998_snd_data *data = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
int j;
|
||||
int ret;
|
||||
|
||||
switch (cpu_dai->id) {
|
||||
case QUATERNARY_TDM_RX_0:
|
||||
case QUATERNARY_TDM_TX_0:
|
||||
if (++(data->quat_tdm_clk_count) == 1) {
|
||||
snd_soc_dai_set_sysclk(cpu_dai,
|
||||
Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
|
||||
TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
}
|
||||
|
||||
codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
|
||||
|
||||
for_each_rtd_codec_dais(rtd, j, codec_dai) {
|
||||
|
||||
if (!strcmp(codec_dai->component->name_prefix,
|
||||
"Left")) {
|
||||
ret = snd_soc_dai_set_fmt(
|
||||
codec_dai, codec_dai_fmt);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev,
|
||||
"Left TDM fmt err:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(codec_dai->component->name_prefix,
|
||||
"Right")) {
|
||||
ret = snd_soc_dai_set_fmt(
|
||||
codec_dai, codec_dai_fmt);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev,
|
||||
"Right TDM slot err:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SLIMBUS_0_RX...SLIMBUS_6_TX:
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msm8998_snd_shutdown(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct msm8998_snd_data *data = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
|
||||
switch (cpu_dai->id) {
|
||||
case QUATERNARY_TDM_RX_0:
|
||||
case QUATERNARY_TDM_TX_0:
|
||||
if (--(data->quat_tdm_clk_count) == 0) {
|
||||
snd_soc_dai_set_sysclk(cpu_dai,
|
||||
Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
|
||||
0, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
}
|
||||
break;
|
||||
case SLIMBUS_0_RX...SLIMBUS_6_TX:
|
||||
case QUATERNARY_MI2S_RX:
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int msm8998_snd_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct msm8998_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
|
||||
int ret;
|
||||
|
||||
if (!sruntime)
|
||||
return 0;
|
||||
|
||||
if (data->stream_prepared[cpu_dai->id]) {
|
||||
sdw_disable_stream(sruntime);
|
||||
sdw_deprepare_stream(sruntime);
|
||||
data->stream_prepared[cpu_dai->id] = false;
|
||||
}
|
||||
|
||||
ret = sdw_prepare_stream(sruntime);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/**
|
||||
* NOTE: there is a strict hw requirement about the ordering of port
|
||||
* enables and actual WSA881x PA enable. PA enable should only happen
|
||||
* after soundwire ports are enabled if not DC on the line is
|
||||
* accumulated resulting in Click/Pop Noise
|
||||
* PA enable/mute are handled as part of codec DAPM and digital mute.
|
||||
*/
|
||||
|
||||
ret = sdw_enable_stream(sruntime);
|
||||
if (ret) {
|
||||
sdw_deprepare_stream(sruntime);
|
||||
return ret;
|
||||
}
|
||||
data->stream_prepared[cpu_dai->id] = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm8998_snd_hw_free(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct msm8998_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
|
||||
|
||||
if (sruntime && data->stream_prepared[cpu_dai->id]) {
|
||||
sdw_disable_stream(sruntime);
|
||||
sdw_deprepare_stream(sruntime);
|
||||
data->stream_prepared[cpu_dai->id] = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops msm8998_be_ops = {
|
||||
.hw_params = msm8998_snd_hw_params,
|
||||
.hw_free = msm8998_snd_hw_free,
|
||||
.prepare = msm8998_snd_prepare,
|
||||
.startup = msm8998_snd_startup,
|
||||
.shutdown = msm8998_snd_shutdown,
|
||||
};
|
||||
|
||||
static int msm8998_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_interval *rate = hw_param_interval(params,
|
||||
SNDRV_PCM_HW_PARAM_RATE);
|
||||
struct snd_interval *channels = hw_param_interval(params,
|
||||
SNDRV_PCM_HW_PARAM_CHANNELS);
|
||||
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
|
||||
|
||||
rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K;
|
||||
channels->min = channels->max = 2;
|
||||
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget msm8998_snd_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
SND_SOC_DAPM_SPK("Left Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("Right Spk", NULL),
|
||||
SND_SOC_DAPM_MIC("Int Mic", NULL),
|
||||
};
|
||||
|
||||
static void msm8998_add_ops(struct snd_soc_card *card)
|
||||
{
|
||||
struct snd_soc_dai_link *link;
|
||||
int i;
|
||||
|
||||
for_each_card_prelinks(card, i, link) {
|
||||
if (link->no_pcm == 1) {
|
||||
link->ops = &msm8998_be_ops;
|
||||
link->be_hw_params_fixup = msm8998_be_hw_params_fixup;
|
||||
}
|
||||
link->init = msm8998_dai_init;
|
||||
}
|
||||
}
|
||||
|
||||
static int msm8998_snd_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card;
|
||||
struct msm8998_snd_data *data;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
|
||||
if (!card)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Allocate the private data */
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
card->driver_name = DRIVER_NAME;
|
||||
card->dapm_widgets = msm8998_snd_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(msm8998_snd_widgets);
|
||||
card->dev = dev;
|
||||
card->owner = THIS_MODULE;
|
||||
dev_set_drvdata(dev, card);
|
||||
ret = qcom_snd_parse_of(card);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data->card = card;
|
||||
snd_soc_card_set_drvdata(card, data);
|
||||
|
||||
msm8998_add_ops(card);
|
||||
return devm_snd_soc_register_card(dev, card);
|
||||
}
|
||||
|
||||
static const struct of_device_id msm8998_snd_device_id[] = {
|
||||
{ .compatible = "qcom,msm8998-sndcard" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, msm8998_snd_device_id);
|
||||
|
||||
static struct platform_driver msm8998_snd_driver = {
|
||||
.probe = msm8998_snd_platform_probe,
|
||||
.driver = {
|
||||
.name = "msm-snd-msm8998",
|
||||
.of_match_table = msm8998_snd_device_id,
|
||||
},
|
||||
};
|
||||
module_platform_driver(msm8998_snd_driver);
|
||||
|
||||
MODULE_DESCRIPTION("msm8998 ASoC Machine Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
Loading…
Add table
Add a link
Reference in a new issue