Compare commits
187 commits
master
...
op5/5.16-w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbc5c9f735 | ||
|
|
4aa04cdc85 | ||
|
|
1667a23e49 | ||
|
|
eee0cdb08a | ||
|
|
1875708601 | ||
|
|
a1d8d9010e | ||
|
|
ef649e6c0c | ||
|
|
193a832101 | ||
|
|
ad13089b85 | ||
|
|
b970f60955 | ||
|
|
13d175a285 | ||
|
|
ce49449d4d | ||
|
|
9646d2632d | ||
|
|
f3ea966e53 | ||
|
|
ab984a91b3 | ||
|
|
f26c3ec996 | ||
|
|
b982d84491 | ||
|
|
d9ada59a34 | ||
|
|
61daf2df97 | ||
|
|
2bc6971f75 | ||
|
|
1964438c0f | ||
|
|
2fd1464c75 | ||
|
|
6fd559371f | ||
|
|
e7f9be7519 | ||
|
|
b9883abfa2 | ||
|
|
a7f6d4f5d2 | ||
|
|
348b250d6e | ||
|
|
9b07deab7d | ||
|
|
2c6faaec9c | ||
|
|
af9bdebc7f | ||
|
|
09273e88c0 | ||
|
|
b6f6faadc7 | ||
|
|
9648db56d6 | ||
|
|
b8d0acc7b5 | ||
|
|
e4454dd8a5 | ||
|
|
8214d51e39 | ||
|
|
dbfc06bf9d | ||
|
|
c8e60b5904 | ||
|
|
631bacc3f5 | ||
|
|
5fbad76da7 | ||
|
|
955846810e | ||
|
|
b6b96f3272 | ||
|
|
6fcf1fe1e2 | ||
|
|
b698aaf4bb | ||
|
|
45231a2944 | ||
|
|
071cc8ce1d | ||
|
|
6bbd2c88ed | ||
|
|
f67fb30a22 | ||
|
|
ec5ec8e50d | ||
|
|
ee88b5c713 | ||
|
|
7dba3ca921 | ||
|
|
ae137a585d | ||
|
|
8a93a26726 | ||
|
|
6e8bad878e | ||
|
|
4edd7c9166 | ||
|
|
98572151bf | ||
|
|
afc73d22c1 | ||
|
|
7f9ecef1b0 | ||
|
|
4ef6b40484 | ||
|
|
c9e5f0cb33 | ||
|
|
4733306ff3 | ||
|
|
c215a02270 | ||
|
|
5679eca4df | ||
|
|
d1c3c3848a | ||
|
|
d8ae300293 | ||
|
|
2cfcce2abf | ||
|
|
50f7a5edfd | ||
|
|
9e2a2c2452 | ||
|
|
d95b982acc | ||
|
|
64ec6966f9 | ||
|
|
8eb0c6e2d6 | ||
|
|
8641f9a558 | ||
|
|
ecd8875f2b | ||
|
|
dfec3843e5 | ||
|
|
5e4390d37a | ||
|
|
e122a6a4e1 | ||
|
|
a0f3bcb6e9 | ||
|
|
6bfe7bc418 | ||
|
|
90170977af | ||
|
|
e4ee78136c | ||
|
|
208744810b | ||
|
|
3102e7aaf8 | ||
|
|
0ae04eda03 | ||
|
|
c72de016c3 | ||
|
|
61271d6273 | ||
|
|
35c64148db | ||
|
|
cd95ecae4a | ||
|
|
bf0b7a1ffa | ||
|
|
e7aa905ace | ||
|
|
324fd2c448 | ||
|
|
9818ab7e2b | ||
|
|
ee4a0e73be | ||
|
|
ba708e4966 | ||
|
|
64361667ec | ||
|
|
42b6c72903 | ||
|
|
7d7936636f | ||
|
|
2a3eeaa730 | ||
|
|
36e759dcab | ||
|
|
5ccc15fc56 | ||
|
|
d805ce6ece | ||
|
|
203c84bacb | ||
|
|
770ff64363 | ||
|
|
fb54cf55d4 | ||
|
|
9d4e49ab2c | ||
|
|
2d498601d7 | ||
|
|
316da4338e | ||
|
|
b2d9f95754 | ||
|
|
298422843e | ||
|
|
932b09a720 | ||
|
|
68fb74869b | ||
|
|
47babd6872 | ||
|
|
2f458a6272 | ||
|
|
c4e8ede8cf | ||
|
|
75d376a90e | ||
|
|
7e3c8189f5 | ||
|
|
c47e38e029 | ||
|
|
a326baf8f2 | ||
|
|
008a5ed048 | ||
|
|
c2e3861fd7 | ||
|
|
8b0d1f9c9c | ||
|
|
44ec014f38 | ||
|
|
f47f056002 | ||
|
|
f1ea33bf02 | ||
|
|
7da5abe66e | ||
|
|
ad3536fd33 | ||
|
|
134e7d3c3f | ||
|
|
4a8417d616 | ||
|
|
44869d20db | ||
|
|
6c2c879a78 | ||
|
|
f833e21372 | ||
|
|
786993afff | ||
|
|
6adc6091be | ||
|
|
819bb21db6 | ||
|
|
8a7b3d8b05 | ||
|
|
c05f3991a1 | ||
|
|
0ef5eb8ae1 | ||
|
|
040a951871 | ||
|
|
71718edee1 | ||
|
|
d22af50489 | ||
|
|
d6a16a91e0 | ||
|
|
af90a1ce6d | ||
|
|
76c4433782 | ||
|
|
4159f402ee | ||
|
|
b38dd2c5b9 | ||
|
|
0dcea98014 | ||
|
|
8058f9b46a | ||
|
|
5d25ef59ae | ||
|
|
1406a16faf | ||
|
|
b2995ca65c | ||
|
|
c3964aae1c | ||
|
|
623540b77d | ||
|
|
6c9da9c1ab | ||
|
|
aa2fb3fd61 | ||
|
|
ccf540041f | ||
|
|
e8d3fd4633 | ||
|
|
fed6e27683 | ||
|
|
e07ec64088 | ||
|
|
fdafc0019a | ||
|
|
845ae94d37 | ||
|
|
7bd23d981f | ||
|
|
d865ddef07 | ||
|
|
b2d482ea0d | ||
|
|
67da594956 | ||
|
|
4d86d0c5b4 | ||
|
|
32e78e5c41 | ||
|
|
f10637ebf1 | ||
|
|
4ccb81c57b | ||
|
|
d2f323864d | ||
|
|
98751f8c78 | ||
|
|
5d7ecb459b | ||
|
|
3a590afb1a | ||
|
|
16bb0ee336 | ||
|
|
64f6436594 | ||
|
|
deeb3aa715 | ||
|
|
3e5b523e39 | ||
|
|
bf0f4ab2ce | ||
|
|
521b4dcb0c | ||
|
|
38b61c0a4c | ||
|
|
a592fe2d95 | ||
|
|
dd1f6900f8 | ||
|
|
b10673b76c | ||
|
|
2a63c83b72 | ||
|
|
2f5fb1d716 | ||
|
|
c5f2e76cb4 | ||
|
|
d582b78bb4 | ||
|
|
a1583a5115 | ||
|
|
73db495db2 |
151 changed files with 29918 additions and 962 deletions
|
|
@ -305,6 +305,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: |
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ description: |
|
|||
sa8155p
|
||||
sc7180
|
||||
sc7280
|
||||
msm8998
|
||||
sdm630
|
||||
sdm660
|
||||
sdm845
|
||||
|
|
@ -207,6 +208,16 @@ properties:
|
|||
- google,senor
|
||||
- const: qcom,sc7280
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- asus,novago-tp370ql
|
||||
- hp,envy-x2
|
||||
- lenovo,miix-630
|
||||
- oneplus,cheeseburger
|
||||
- oneplus,dumpling
|
||||
- qcom,msm8998-mtp
|
||||
- const: qcom,msm8998
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- xiaomi,lavender
|
||||
|
|
|
|||
|
|
@ -1,172 +0,0 @@
|
|||
Qualcomm Technologies, Inc. CPUFREQ Bindings
|
||||
|
||||
CPUFREQ HW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
|
||||
SoCs to manage frequency in hardware. It is capable of controlling frequency
|
||||
for multiple clusters.
|
||||
|
||||
Properties:
|
||||
- compatible
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: must be "qcom,cpufreq-hw" or "qcom,cpufreq-epss".
|
||||
|
||||
- clocks
|
||||
Usage: required
|
||||
Value type: <phandle> From common clock binding.
|
||||
Definition: clock handle for XO clock and GPLL0 clock.
|
||||
|
||||
- clock-names
|
||||
Usage: required
|
||||
Value type: <string> From common clock binding.
|
||||
Definition: must be "xo", "alternate".
|
||||
|
||||
- reg
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Addresses and sizes for the memory of the HW bases in
|
||||
each frequency domain.
|
||||
- reg-names
|
||||
Usage: Optional
|
||||
Value type: <string>
|
||||
Definition: Frequency domain name i.e.
|
||||
"freq-domain0", "freq-domain1".
|
||||
|
||||
- #freq-domain-cells:
|
||||
Usage: required.
|
||||
Definition: Number of cells in a freqency domain specifier.
|
||||
|
||||
* Property qcom,freq-domain
|
||||
Devices supporting freq-domain must set their "qcom,freq-domain" property with
|
||||
phandle to a cpufreq_hw followed by the Domain ID(0/1) in the CPU DT node.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster switch
|
||||
DCVS state together.
|
||||
|
||||
/ {
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
CPU0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_0>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
L2_0: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
L3_0: l3-cache {
|
||||
compatible = "cache";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
CPU1: cpu@100 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x100>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_100>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
L2_100: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU2: cpu@200 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x200>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_200>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
L2_200: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU3: cpu@300 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x300>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_300>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
L2_300: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU4: cpu@400 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x400>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_400>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
L2_400: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU5: cpu@500 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x500>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_500>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
L2_500: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU6: cpu@600 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x600>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_600>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
L2_600: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU7: cpu@700 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x700>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_700>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
L2_700: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
soc {
|
||||
cpufreq_hw: cpufreq@17d43000 {
|
||||
compatible = "qcom,cpufreq-hw";
|
||||
reg = <0x17d43000 0x1400>, <0x17d45800 0x1400>;
|
||||
reg-names = "freq-domain0", "freq-domain1";
|
||||
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>;
|
||||
clock-names = "xo", "alternate";
|
||||
|
||||
#freq-domain-cells = <1>;
|
||||
};
|
||||
}
|
||||
242
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml
Normal file
242
Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/cpufreq/cpufreq-qcom-hw.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies, Inc. CPUFREQ
|
||||
|
||||
maintainers:
|
||||
- Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
|
||||
description: |
|
||||
|
||||
CPUFREQ HW is a hardware engine used by some Qualcomm Technologies, Inc. (QTI)
|
||||
SoCs to manage frequency in hardware. It is capable of controlling frequency
|
||||
for multiple clusters.
|
||||
|
||||
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
|
||||
|
||||
- description: v2 of CPUFREQ HW (EPSS)
|
||||
items:
|
||||
- enum:
|
||||
- qcom,sm8250-cpufreq-epss
|
||||
- const: qcom,cpufreq-epss
|
||||
|
||||
reg: {}
|
||||
|
||||
reg-names: {}
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: XO Clock
|
||||
- description: GPLL0 Clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: xo
|
||||
- const: alternate
|
||||
|
||||
'#freq-domain-cells':
|
||||
const: 1
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,cpufreq-hw-8998
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
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
|
||||
maxItems: 6
|
||||
items:
|
||||
- const: "osm-domain0"
|
||||
- const: "freq-domain0"
|
||||
- const: "osm-domain1"
|
||||
- const: "freq-domain1"
|
||||
- const: "osm-acd0"
|
||||
- const: "osm-acd1"
|
||||
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
- description: Frequency domain 0 register region
|
||||
- description: Frequency domain 1 register region
|
||||
- description: Frequency domain 2 register region
|
||||
reg-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
- const: "freq-domain0"
|
||||
- const: "freq-domain1"
|
||||
- const: "freq-domain2"
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#freq-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
|
||||
// Example 1: Dual-cluster, Quad-core per cluster. CPUs within a cluster
|
||||
// switch DCVS state together.
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
CPU0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_0>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
L2_0: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
L3_0: l3-cache {
|
||||
compatible = "cache";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
CPU1: cpu@100 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x100>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_100>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
L2_100: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU2: cpu@200 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x200>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_200>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
L2_200: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU3: cpu@300 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x300>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_300>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
L2_300: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU4: cpu@400 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x400>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_400>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
L2_400: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU5: cpu@500 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x500>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_500>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
L2_500: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU6: cpu@600 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x600>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_600>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
L2_600: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
|
||||
CPU7: cpu@700 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x700>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_700>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
L2_700: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpufreq@17d43000 {
|
||||
compatible = "qcom,cpufreq-hw";
|
||||
reg = <0x17d43000 0x1400>, <0x17d45800 0x1400>;
|
||||
reg-names = "freq-domain0", "freq-domain1";
|
||||
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>;
|
||||
clock-names = "xo", "alternate";
|
||||
|
||||
#freq-domain-cells = <1>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/boe,bf060y8m-aj0.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: BOE BF060Y8M-AJ0 5.99" 1080x2160 AMOLED Panel
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
description: |
|
||||
This is a 5.99" 1080x2160 16.7M Color active matrix AMOLED
|
||||
video mode panel module on MIPI-DSI 4-Lane interface, GGRB
|
||||
pixel arrangement, 63 micrometers pitch, with an active
|
||||
area of 68.04 x 136.08 millimeters.
|
||||
Each pixel is divided into red and green dots, or blue and
|
||||
green dots, and two pixels share red or blue dots which are
|
||||
arranged in vertical stripe.
|
||||
The DriverIC for this panel module is SW43404.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: boe,bf060y8m-aj0
|
||||
reg: true
|
||||
reset-gpios: true
|
||||
vcc-supply:
|
||||
description: Core (TSP) voltage supply (2.70-3.60V)
|
||||
vddio-supply:
|
||||
description: I/O voltage supply (1.62-1.98V)
|
||||
vci-supply:
|
||||
description: DriverIC Operation supply (2.60-3.60V)
|
||||
elvdd-supply:
|
||||
description: EL Driving positive (VDD) supply (4.40-4.80V)
|
||||
elvss-supply:
|
||||
description: EL Driving negative (VSS) supply (-5.00V to -1.40V)
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
panel@0 {
|
||||
compatible = "boe,bf060y8m,aj0";
|
||||
reg = <0>;
|
||||
|
||||
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>;
|
||||
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/novatek,nt35950.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Novatek NT35950-based display panels
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
description: |
|
||||
The nt35950 IC from Novatek is a Driver IC used to drive MIPI-DSI panels,
|
||||
with Static RAM for content retention in command mode and also supports
|
||||
video mode with VESA Frame Buffer Compression or Display Stream Compression
|
||||
on single, or dual dsi port(s).
|
||||
This DDIC is also capable of upscaling an input image to the panel's native
|
||||
resolution, for example it can upscale a 1920x1080 input to 3840x2160 with
|
||||
either bilinear interpolation or pixel duplication.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- sharp,ls055d1sx04
|
||||
- const: novatek,nt35950
|
||||
description: This indicates the panel manufacturer of the panel
|
||||
that is in turn using the NT35950 panel driver. The compatible
|
||||
string determines how the NT35950 panel driver shall be configured
|
||||
to work with the indicated panel. The novatek,nt35950 compatible shall
|
||||
always be provided as a fallback.
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description: phandle of gpio for reset line - This should be 8mA, gpio
|
||||
can be configured using mux, pinctrl, pinctrl-names (active high)
|
||||
|
||||
avdd-supply:
|
||||
description: positive boost supply regulator
|
||||
avee-supply:
|
||||
description: negative boost supply regulator
|
||||
dvdd-supply:
|
||||
description: regulator that supplies the digital voltage
|
||||
vddio-supply:
|
||||
description: regulator that supplies the I/O voltage
|
||||
|
||||
backlight: true
|
||||
ports: true
|
||||
reg: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reset-gpios
|
||||
- avdd-supply
|
||||
- avee-supply
|
||||
- dvdd-supply
|
||||
- vddio-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "sharp,ls055d1sx04", "novatek,nt35950";
|
||||
reg = <0>;
|
||||
|
||||
backlight = <&pmi8998_wled>;
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
avdd-supply = <&lab>;
|
||||
avee-supply = <&ibb>;
|
||||
dvdd-supply = <&disp_dvdd_vreg>;
|
||||
vddio-supply = <&vreg_l14a_1p85>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
panel_in0: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
panel_in1: endpoint {
|
||||
remote-endpoint = <&dsi1_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
|
@ -55,6 +55,10 @@ properties:
|
|||
- samsung,sofef00
|
||||
# Shangai Top Display Optoelectronics 7" TL070WSH30 1024x600 TFT LCD panel
|
||||
- tdo,tl070wsh30
|
||||
# Sony Kirin nt36672a Truly FHD+ IPS LCD panel
|
||||
- sony,kirin-nt36672a-truly
|
||||
# Sony mermaid nt36672a Tianma FHD+ IPS LCD panel
|
||||
- sony,mermaid-nt36672a-tianma
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/sony,discovery-td4322-innolux.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: SONY Discovery TD4322 Innolux 6.0" 1080×1920 LCD Panel
|
||||
|
||||
maintainers:
|
||||
- Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
|
||||
description: |+
|
||||
This panel seems to only be found in the Sony Xperia XA2 Ultra
|
||||
smartphone and we have no straightforward way of
|
||||
actually getting the correct model number,
|
||||
as no schematics are released publicly.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sony,discovery-td4322-innolux
|
||||
reg: true
|
||||
reset-gpios: true
|
||||
vdd-supply:
|
||||
description: core voltage supply
|
||||
vddio-supply:
|
||||
description: vddio supply
|
||||
vsp-supply:
|
||||
description: positive voltage supply
|
||||
vsn-supply:
|
||||
description: negative voltage supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
- vddio-supply
|
||||
- vsp-supply
|
||||
- vsn-supply
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
panel@0 {
|
||||
reg = <0>;
|
||||
compatible = "sony,discovery-td4322-innolux";
|
||||
|
||||
vdd-supply = <&pm8916_l8>;
|
||||
vddio-supply = <&pm8916_l6>;
|
||||
vsp-supply = <&lab>;
|
||||
vsn-supply = <&ibb>;
|
||||
reset-gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/sony,pioneer-td4322-truly.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: SONY Pioneer TD4322 Truly 5.2" 1080×1920 LCD Panel
|
||||
|
||||
maintainers:
|
||||
- Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
|
||||
description: |+
|
||||
This panel seems to only be found in the Sony Xperia XA2
|
||||
smartphone and we have no straightforward way of
|
||||
actually getting the correct model number,
|
||||
as no schematics are released publicly.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sony,pioneer-td4322-truly
|
||||
reg: true
|
||||
reset-gpios: true
|
||||
vdd-supply:
|
||||
description: core voltage supply
|
||||
vddio-supply:
|
||||
description: vddio supply
|
||||
vsp-supply:
|
||||
description: positive voltage supply
|
||||
vsn-supply:
|
||||
description: negative voltage supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
- vddio-supply
|
||||
- vsp-supply
|
||||
- vsn-supply
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
panel@0 {
|
||||
reg = <0>;
|
||||
compatible = "sony,pioneer-td4322-truly";
|
||||
|
||||
vdd-supply = <&pm8916_l8>;
|
||||
vddio-supply = <&pm8916_l6>;
|
||||
vsp-supply = <&lab>;
|
||||
vsn-supply = <&ibb>;
|
||||
reset-gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/sony,voyager-td4328-tianma.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: SONY Voyager TD4328 Tianma 6.0" 1080×2160 LCD Panel
|
||||
|
||||
maintainers:
|
||||
- Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
|
||||
description: |+
|
||||
This panel seems to only be found in the Sony Xperia XA2 Plus
|
||||
smartphone and we have no straightforward way of
|
||||
actually getting the correct model number,
|
||||
as no schematics are released publicly.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sony,voyager-td4328-tianma
|
||||
reg: true
|
||||
reset-gpios: true
|
||||
vdd-supply:
|
||||
description: core voltage supply
|
||||
vddio-supply:
|
||||
description: vddio supply
|
||||
vsp-supply:
|
||||
description: positive voltage supply
|
||||
vsn-supply:
|
||||
description: negative voltage supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
- vddio-supply
|
||||
- vsp-supply
|
||||
- vsn-supply
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
panel@0 {
|
||||
reg = <0>;
|
||||
compatible = "sony,voyager-td4328-tianma";
|
||||
|
||||
vdd-supply = <&pm8916_l8>;
|
||||
vddio-supply = <&pm8916_l6>;
|
||||
vsp-supply = <&lab>;
|
||||
vsn-supply = <&ibb>;
|
||||
reset-gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
Qualcomm Universal Peripheral (QUP) I2C controller
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be:
|
||||
* "qcom,i2c-qup-v1.1.1" for 8660, 8960 and 8064.
|
||||
* "qcom,i2c-qup-v2.1.1" for 8974 v1.
|
||||
* "qcom,i2c-qup-v2.2.1" for 8974 v2 and later.
|
||||
- reg: Should contain QUP register address and length.
|
||||
- interrupts: Should contain I2C interrupt.
|
||||
|
||||
- clocks: A list of phandles + clock-specifiers, one for each entry in
|
||||
clock-names.
|
||||
- clock-names: Should contain:
|
||||
* "core" for the core clock
|
||||
* "iface" for the AHB clock
|
||||
|
||||
- #address-cells: Should be <1> Address cells for i2c device address
|
||||
- #size-cells: Should be <0> as i2c addresses have no size component
|
||||
|
||||
Optional properties:
|
||||
- clock-frequency: Should specify the desired i2c bus clock frequency in Hz,
|
||||
defaults to 100kHz if omitted.
|
||||
|
||||
Child nodes should conform to i2c bus binding.
|
||||
|
||||
Example:
|
||||
|
||||
i2c@f9924000 {
|
||||
compatible = "qcom,i2c-qup-v2.2.1";
|
||||
reg = <0xf9924000 0x1000>;
|
||||
interrupts = <0 96 0>;
|
||||
|
||||
clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
|
||||
clock-names = "core", "iface";
|
||||
|
||||
clock-frequency = <355000>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
101
Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
Normal file
101
Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
|
||||
$id: http://devicetree.org/schemas/i2c/qcom,i2c-qup.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Universal Peripheral (QUP) I2C controller
|
||||
|
||||
maintainers:
|
||||
- Andy Gross <agross@kernel.org>
|
||||
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
|
||||
description: Binding for Qualcomm "QUP" I2C controllers
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/i2c/i2c-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,i2c-qup-v1.1.1
|
||||
- qcom,i2c-qup-v2.1.1
|
||||
- qcom,i2c-qup-v2.2.1
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: QUP I2C register iospace
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Core QUP I2C clock
|
||||
- description: AHB clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: iface
|
||||
|
||||
clock-frequency:
|
||||
minimum: 100000
|
||||
maximum: 1000000
|
||||
default: 100000
|
||||
|
||||
dmas:
|
||||
items:
|
||||
- description: RX DMA Channel phandle
|
||||
- description: TX DMA Channel phandle
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
qcom,noise-reject-sda:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Noise rejection level for the SDA line.
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
default: 0
|
||||
|
||||
qcom,noise-reject-scl:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Noise rejection level for the SCL line.
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
default: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-msm8998.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
i2c@c175000 {
|
||||
compatible = "qcom,i2c-qup-v2.2.1";
|
||||
reg = <0x0c175000 0x600>;
|
||||
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>,
|
||||
<&gcc GCC_BLSP1_AHB_CLK>;
|
||||
clock-names = "core", "iface";
|
||||
clock-frequency = <400000>;
|
||||
dmas = <&blsp_dma 4>, <&blsp_dma 5>;
|
||||
dma-names = "rx", "tx";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
|
@ -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>;
|
||||
};
|
||||
128
Documentation/devicetree/bindings/input/qcom,spmi-haptics.yaml
Normal file
128
Documentation/devicetree/bindings/input/qcom,spmi-haptics.yaml
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright 2020 Unisoc Inc.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/input/qcom,spmi-haptics.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies Inc PMI8998 spmi haptics
|
||||
|
||||
maintainers:
|
||||
- Caleb Connolly <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 mode.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,pmi8998-haptics
|
||||
- qcom,pmi8996-haptics
|
||||
- qcom,pmi8941-haptics
|
||||
- const: qcom,spmi-haptics
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: short circuit interrupt
|
||||
- description: play interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: short
|
||||
- const: play
|
||||
|
||||
qcom,actuator-type:
|
||||
description: |
|
||||
The type of actuator attached to the hardware.
|
||||
Allowed values are,
|
||||
0 - HAP_TYPE_LRA
|
||||
1 - HAP_TYPE_ERM
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1 ]
|
||||
default: 0
|
||||
|
||||
qcom,wave-shape:
|
||||
description: |
|
||||
Selects the wave shape to use.
|
||||
Allowed values are,
|
||||
0 - HAP_WAVE_SINE
|
||||
1 - HAP_WAVE_SQUARE
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1 ]
|
||||
default: 0
|
||||
|
||||
qcom,play-mode:
|
||||
description: |
|
||||
Selects the play mode to use.
|
||||
Allowed values are,
|
||||
0 - HAP_PLAY_DIRECT
|
||||
1 - HAP_PLAY_BUFFER
|
||||
2 - HAP_PLAY_AUDIO
|
||||
3 - HAP_PLAY_PWM
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
default: 2
|
||||
|
||||
qcom,wave-play-rate-us:
|
||||
description: |
|
||||
Wave play rate in microseconds, 1/f where f
|
||||
is the resonant frequency of the actuator.
|
||||
minimum: 0
|
||||
maximum: 20475
|
||||
|
||||
qcom,brake-pattern:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
description: |
|
||||
The brake pattern is an array of amplitudes
|
||||
used to brake the haptics. Allowed values are,
|
||||
0 - 0V
|
||||
1 - Vmax/4
|
||||
2 - Vmax/2
|
||||
3 - Vmax
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
default: [0x3, 0x3, 0x2, 0x1]
|
||||
items:
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- qcom,wave-play-rate-us
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/spmi/spmi.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/input/qcom,spmi-haptics.h>
|
||||
|
||||
pmic@3 {
|
||||
compatible = "qcom,pmi8998", "qcom,spmi-pmic";
|
||||
reg = <0x3 SPMI_USID>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmi8998_haptics: haptics@c000 {
|
||||
compatible = "qcom,pmi8998-haptics", "qcom,spmi-haptics";
|
||||
reg = <0xc000>;
|
||||
|
||||
interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
|
||||
<0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
|
||||
interrupt-names = "short", "play";
|
||||
|
||||
qcom,wave-shape = <HAP_WAVE_SINE>;
|
||||
qcom,wave-play-rate-us = <4255>;
|
||||
qcom,play-mode = <HAP_PLAY_BUFFER>;
|
||||
qcom,brake-pattern = <0x3 0x3 0x2 0x1>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/input/touchscreen/nt36xxx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Novatek NT36xxx series touchscreen controller Bindings
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <kholk11@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: touchscreen.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: novatek,nt36525
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply:
|
||||
description: Power supply regulator for VDD pin
|
||||
|
||||
vio-supply:
|
||||
description: Power supply regulator on VDD-IO pin
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
touchscreen@62 {
|
||||
compatible = "novatek,nt36525";
|
||||
reg = <0x62>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <45 IRQ_TYPE_EDGE_RISING>;
|
||||
reset-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
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>;
|
||||
};
|
||||
158
Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
Normal file
158
Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/leds-qcom-lpg.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Light Pulse Generator
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
|
||||
description: >
|
||||
The Qualcomm Light Pulse Generator consists of three different hardware blocks;
|
||||
a ramp generator with lookup table, the light pulse generator and a three
|
||||
channel current sink. These blocks are found in a wide range of Qualcomm PMICs.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pm8150b-lpg
|
||||
- qcom,pm8150l-lpg
|
||||
- qcom,pm8916-pwm
|
||||
- qcom,pm8941-lpg
|
||||
- qcom,pm8994-lpg
|
||||
- qcom,pmi8994-lpg
|
||||
- qcom,pmi8998-lpg
|
||||
|
||||
"#pwm-cells":
|
||||
const: 2
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
qcom,power-source:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
power-source used to drive the output, as defined in the datasheet.
|
||||
Should be specified if the TRILED block is present
|
||||
|
||||
qcom,dtest:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description: >
|
||||
A list of integer pairs, where each pair represent the dtest line the
|
||||
particular channel should be connected to and the flags denoting how the
|
||||
value should be outputed, as defined in the datasheet. The number of
|
||||
pairs should be the same as the number of channels.
|
||||
|
||||
multi-led:
|
||||
type: object
|
||||
$ref: leds-class-multicolor.yaml#
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
"^led@[0-9a-f]$":
|
||||
type: object
|
||||
$ref: common.yaml#
|
||||
|
||||
patternProperties:
|
||||
"^led@[0-9a-f]$":
|
||||
type: object
|
||||
$ref: common.yaml#
|
||||
|
||||
properties:
|
||||
reg: true
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
lpg {
|
||||
compatible = "qcom,pmi8994-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
qcom,power-source = <1>;
|
||||
|
||||
qcom,dtest = <0 0
|
||||
0 0
|
||||
0 0
|
||||
4 1>;
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
label = "green:user1";
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
label = "green:user0";
|
||||
default-state = "on";
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
label = "green:user2";
|
||||
};
|
||||
|
||||
led@4 {
|
||||
reg = <4>;
|
||||
label = "green:user3";
|
||||
};
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
lpg {
|
||||
compatible = "qcom,pmi8994-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
qcom,power-source = <1>;
|
||||
|
||||
multi-led {
|
||||
color = <LED_COLOR_ID_MULTI>;
|
||||
label = "rgb:notification";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
- |
|
||||
lpg {
|
||||
compatible = "qcom,pm8916-pwm";
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
...
|
||||
112
Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml
Normal file
112
Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/sony,imx300.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sony 1/2.3-Inch 25Mpixel Stacked CMOS Digital Image Sensor
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
description: |-
|
||||
The Sony IMX300 is a 1/2.3-inch Stacked CMOS (Exmor-RS) digital image
|
||||
sensor with a pixel size of 1.08um and an active array size of
|
||||
5948H x 4140V. It is programmable through I2C interface at address 0x10.
|
||||
Image data is sent through MIPI CSI-2, which is configured as either 2 or
|
||||
4 data lanes.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sony,imx300
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
vdig-supply:
|
||||
description:
|
||||
Digital I/O voltage supply, 1.15-1.20 volts
|
||||
|
||||
vana-supply:
|
||||
description:
|
||||
Analog voltage supply, 2.2 volts
|
||||
|
||||
vddl-supply:
|
||||
description:
|
||||
Digital core voltage supply, 1.8 volts
|
||||
|
||||
reset-gpios:
|
||||
description: |-
|
||||
Reference to the GPIO connected to the xclr pin, if any.
|
||||
Must be released (set high) after all supplies are applied.
|
||||
|
||||
# See ../video-interfaces.txt for more details
|
||||
port:
|
||||
type: object
|
||||
properties:
|
||||
endpoint:
|
||||
type: object
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
description: |-
|
||||
The driver only supports four-lane operation.
|
||||
items:
|
||||
- const: 0
|
||||
- const: 1
|
||||
- const: 2
|
||||
- const: 3
|
||||
|
||||
clock-noncontinuous: true
|
||||
|
||||
link-frequencies:
|
||||
$ref: /schemas/types.yaml#/definitions/uint64-array
|
||||
description:
|
||||
Allowed data bus frequencies. The driver currently needs
|
||||
to switch between 780000000 and 480000000 Hz in order to
|
||||
guarantee functionality of all modes.
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- vana-supply
|
||||
- vdig-supply
|
||||
- vddl-supply
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
imx300: sensor@10 {
|
||||
compatible = "sony,imx300";
|
||||
reg = <0x10>;
|
||||
clocks = <&imx300_xclk>;
|
||||
vana-supply = <&imx300_vana>; /* 2.2v */
|
||||
vdig-supply = <&imx300_vdig>; /* 1.2v */
|
||||
vddl-supply = <&imx300_vddl>; /* 1.8v */
|
||||
|
||||
port {
|
||||
imx300_0: endpoint {
|
||||
remote-endpoint = <&csi1_ep>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
clock-noncontinuous;
|
||||
link-frequencies = /bits/ 64 <780000000 480000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1,130 +1 @@
|
|||
QCOM CPR (Core Power Reduction)
|
||||
|
||||
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 adjustments to the voltage to save power
|
||||
and meet silicon characteristic requirements.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: should be "qcom,qcs404-cpr", "qcom,cpr" for qcs404
|
||||
|
||||
- reg:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: base address and size of the rbcpr register region
|
||||
|
||||
- interrupts:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should specify the CPR interrupt
|
||||
|
||||
- clocks:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: phandle to the reference clock
|
||||
|
||||
- clock-names:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "ref"
|
||||
|
||||
- vdd-apc-supply:
|
||||
Usage: required
|
||||
Value type: <phandle>
|
||||
Definition: phandle to the vdd-apc-supply regulator
|
||||
|
||||
- #power-domain-cells:
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: should be 0
|
||||
|
||||
- operating-points-v2:
|
||||
Usage: required
|
||||
Value type: <phandle>
|
||||
Definition: A phandle to the OPP table containing the
|
||||
performance states supported by the CPR
|
||||
power domain
|
||||
|
||||
- acc-syscon:
|
||||
Usage: optional
|
||||
Value type: <phandle>
|
||||
Definition: phandle to syscon for writing ACC settings
|
||||
|
||||
- nvmem-cells:
|
||||
Usage: required
|
||||
Value type: <phandle>
|
||||
Definition: phandle to nvmem cells containing the data
|
||||
that makes up a fuse corner, for each fuse corner.
|
||||
As well as the CPR fuse revision.
|
||||
|
||||
- nvmem-cell-names:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: should be "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"
|
||||
for qcs404.
|
||||
|
||||
Example:
|
||||
|
||||
cpr_opp_table: cpr-opp-table {
|
||||
compatible = "operating-points-v2-qcom-level";
|
||||
|
||||
cpr_opp1: opp1 {
|
||||
opp-level = <1>;
|
||||
qcom,opp-fuse-level = <1>;
|
||||
};
|
||||
cpr_opp2: opp2 {
|
||||
opp-level = <2>;
|
||||
qcom,opp-fuse-level = <2>;
|
||||
};
|
||||
cpr_opp3: opp3 {
|
||||
opp-level = <3>;
|
||||
qcom,opp-fuse-level = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
power-controller@b018000 {
|
||||
compatible = "qcom,qcs404-cpr", "qcom,cpr";
|
||||
reg = <0x0b018000 0x1000>;
|
||||
interrupts = <0 15 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&xo_board>;
|
||||
clock-names = "ref";
|
||||
vdd-apc-supply = <&pms405_s3>;
|
||||
#power-domain-cells = <0>;
|
||||
operating-points-v2 = <&cpr_opp_table>;
|
||||
acc-syscon = <&tcsr>;
|
||||
|
||||
nvmem-cells = <&cpr_efuse_quot_offset1>,
|
||||
<&cpr_efuse_quot_offset2>,
|
||||
<&cpr_efuse_quot_offset3>,
|
||||
<&cpr_efuse_init_voltage1>,
|
||||
<&cpr_efuse_init_voltage2>,
|
||||
<&cpr_efuse_init_voltage3>,
|
||||
<&cpr_efuse_quot1>,
|
||||
<&cpr_efuse_quot2>,
|
||||
<&cpr_efuse_quot3>,
|
||||
<&cpr_efuse_ring1>,
|
||||
<&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";
|
||||
};
|
||||
This file has been moved to ../../soc/qcom/qcom,cpr.yaml
|
||||
|
|
|
|||
167
Documentation/devicetree/bindings/soc/qcom/qcom,cpr.yaml
Normal file
167
Documentation/devicetree/bindings/soc/qcom/qcom,cpr.yaml
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/soc/qcom/qcom,cpr.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Qualcomm Core Power Reduction (CPR)
|
||||
|
||||
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 adjustments to the voltage to save power
|
||||
and meet silicon characteristic requirements.
|
||||
|
||||
maintainers:
|
||||
- Niklas Cassel <nks@flawful.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,qcs404-cpr
|
||||
- const: qcom,cpr
|
||||
|
||||
reg:
|
||||
description: Base address and size of the RBCPR register region
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ref
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: CPR reference clock
|
||||
|
||||
vdd-apc-supply:
|
||||
description: Autonomous Phase Control (APC) power supply
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 0
|
||||
|
||||
acc-syscon:
|
||||
description: phandle to syscon for writing ACC settings
|
||||
|
||||
nvmem-cells:
|
||||
minItems: 9
|
||||
maxItems: 32
|
||||
description: Cells containing the fuse corners and revision data
|
||||
|
||||
nvmem-cell-names:
|
||||
minItems: 9
|
||||
maxItems: 32
|
||||
|
||||
operating-points-v2: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clock-names
|
||||
- clocks
|
||||
- vdd-apc-supply
|
||||
- "#power-domain-cells"
|
||||
- nvmem-cells
|
||||
- nvmem-cell-names
|
||||
- operating-points-v2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@100 {
|
||||
compatible = "arm,cortex-a53";
|
||||
device_type = "cpu";
|
||||
reg = <0x100>;
|
||||
operating-points-v2 = <&cpu_opp_table>;
|
||||
power-domains = <&cpr>;
|
||||
power-domain-names = "cpr";
|
||||
};
|
||||
};
|
||||
|
||||
cpu_opp_table: cpu-opp-table {
|
||||
compatible = "operating-points-v2-kryo-cpu";
|
||||
opp-shared;
|
||||
|
||||
opp-1094400000 {
|
||||
opp-hz = /bits/ 64 <1094400000>;
|
||||
required-opps = <&cpr_opp1>;
|
||||
};
|
||||
opp-1248000000 {
|
||||
opp-hz = /bits/ 64 <1248000000>;
|
||||
required-opps = <&cpr_opp2>;
|
||||
};
|
||||
opp-1401600000 {
|
||||
opp-hz = /bits/ 64 <1401600000>;
|
||||
required-opps = <&cpr_opp3>;
|
||||
};
|
||||
};
|
||||
|
||||
cpr_opp_table: cpr-opp-table {
|
||||
compatible = "operating-points-v2-qcom-level";
|
||||
|
||||
cpr_opp1: opp1 {
|
||||
opp-level = <1>;
|
||||
qcom,opp-fuse-level = <1>;
|
||||
};
|
||||
cpr_opp2: opp2 {
|
||||
opp-level = <2>;
|
||||
qcom,opp-fuse-level = <2>;
|
||||
};
|
||||
cpr_opp3: opp3 {
|
||||
opp-level = <3>;
|
||||
qcom,opp-fuse-level = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
power-controller@b018000 {
|
||||
compatible = "qcom,qcs404-cpr", "qcom,cpr";
|
||||
reg = <0x0b018000 0x1000>;
|
||||
interrupts = <0 15 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&xo_board>;
|
||||
clock-names = "ref";
|
||||
vdd-apc-supply = <&pms405_s3>;
|
||||
#power-domain-cells = <0>;
|
||||
operating-points-v2 = <&cpr_opp_table>;
|
||||
acc-syscon = <&tcsr>;
|
||||
|
||||
nvmem-cells = <&cpr_efuse_quot_offset1>,
|
||||
<&cpr_efuse_quot_offset2>,
|
||||
<&cpr_efuse_quot_offset3>,
|
||||
<&cpr_efuse_init_voltage1>,
|
||||
<&cpr_efuse_init_voltage2>,
|
||||
<&cpr_efuse_init_voltage3>,
|
||||
<&cpr_efuse_quot1>,
|
||||
<&cpr_efuse_quot2>,
|
||||
<&cpr_efuse_quot3>,
|
||||
<&cpr_efuse_ring1>,
|
||||
<&cpr_efuse_ring2>,
|
||||
<&cpr_efuse_ring3>,
|
||||
<&cpr_efuse_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";
|
||||
};
|
||||
...
|
||||
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";
|
||||
};
|
||||
...
|
||||
|
|
@ -828,6 +828,8 @@ patternProperties:
|
|||
description: Nokia
|
||||
"^nordic,.*":
|
||||
description: Nordic Semiconductor
|
||||
"^novatek,.*":
|
||||
description: Novatek Microelectronics Corp.
|
||||
"^novtech,.*":
|
||||
description: NovTech, Inc.
|
||||
"^nutsboard,.*":
|
||||
|
|
@ -852,6 +854,8 @@ patternProperties:
|
|||
description: OLIMEX Ltd.
|
||||
"^olpc,.*":
|
||||
description: One Laptop Per Child
|
||||
"^oneplus,.*":
|
||||
description: OnePlus Technology (Shenzhen) Co., Ltd.
|
||||
"^onion,.*":
|
||||
description: Onion Corporation
|
||||
"^onnn,.*":
|
||||
|
|
|
|||
15
MAINTAINERS
15
MAINTAINERS
|
|
@ -15740,9 +15740,15 @@ M: Niklas Cassel <nks@flawful.org>
|
|||
L: linux-pm@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/power/avs/qcom,cpr.txt
|
||||
F: Documentation/devicetree/bindings/soc/qcom/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
|
||||
|
|
@ -17758,6 +17764,13 @@ T: git git://linuxtv.org/media_tree.git
|
|||
F: Documentation/devicetree/bindings/media/i2c/imx290.txt
|
||||
F: drivers/media/i2c/imx290.c
|
||||
|
||||
SONY IMX300 SENSOR DRIVER
|
||||
M: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx300.yaml
|
||||
F: drivers/media/i2c/imx300.c
|
||||
|
||||
SONY IMX319 SENSOR DRIVER
|
||||
M: Bingbu Cao <bingbu.cao@intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-nile-pioneer.dtb
|
|||
dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-nile-voyager.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += sdm636-sony-xperia-ganges-mermaid.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += sdm660-xiaomi-lavender.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += sdm660-xiaomi-platina.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r1.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r2.dtb
|
||||
dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r3.dtb
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "pmi8994.dtsi"
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/gpio/gpio.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>
|
||||
|
|
@ -671,6 +672,54 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pmi8994_lpg {
|
||||
qcom,power-source = <1>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pmi8994_mpp2_userled4>;
|
||||
|
||||
qcom,dtest = <0 0
|
||||
0 0
|
||||
0 0
|
||||
4 1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
label = "green:user1";
|
||||
|
||||
linux,default-trigger = "heartbeat";
|
||||
default-state = "on";
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
label = "green:user0";
|
||||
default-state = "on";
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
label = "green:user2";
|
||||
};
|
||||
|
||||
led@4 {
|
||||
reg = <4>;
|
||||
label = "green:user3";
|
||||
};
|
||||
};
|
||||
|
||||
&pmi8994_mpps {
|
||||
pmi8994_mpp2_userled4: mpp2-userled4-state {
|
||||
pins = "mpp2";
|
||||
function = "sink";
|
||||
|
||||
output-low;
|
||||
qcom,dtest = <4>;
|
||||
};
|
||||
};
|
||||
|
||||
&pmi8994_spmi_regulators {
|
||||
vdd_gfx: s2@1700 {
|
||||
reg = <0x1700 0x100>;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,15 @@
|
|||
chassis-type = "handset";
|
||||
qcom,board-id = <0x02000b 0x10>;
|
||||
|
||||
/* This part enables graphical output via bootloader-enabled display */
|
||||
chosen {
|
||||
bootargs = "earlycon=tty0 console=tty0 clk_ignore_unused";
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
|
||||
/*
|
||||
* Until we hook up type-c detection, we
|
||||
* have to stick with this. But it works.
|
||||
|
|
@ -48,6 +57,8 @@
|
|||
compatible = "gpio-keys";
|
||||
input-name = "extra-kb-keys";
|
||||
label = "Keyboard extra keys";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&gpio_kb_pins_extra>;
|
||||
|
||||
|
|
@ -100,6 +111,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";
|
||||
input-name = "side-buttons";
|
||||
|
|
@ -180,6 +224,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";
|
||||
|
|
@ -192,8 +283,62 @@
|
|||
};
|
||||
};
|
||||
|
||||
&adreno_gpu {
|
||||
status = "ok";
|
||||
|
||||
zap-shader {
|
||||
memory-region = <&zap_shader_region>;
|
||||
firmware-name = "qcom/a540_zap.mbn";
|
||||
};
|
||||
};
|
||||
|
||||
&adreno_smmu {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&apc_cprh {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&blsp1_i2c6 {
|
||||
status = "ok";
|
||||
|
||||
gpioext0: gpio-expander@58 {
|
||||
compatible = "awinic,aw9523-pinctrl";
|
||||
reg = <0x58>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <50 IRQ_TYPE_EDGE_FALLING>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&gpioext0 0 0 16>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
pinctrl-0 = <&gpio_expander_int_n>, <&gpio_expander_rst_n>;
|
||||
pinctrl-names = "default";
|
||||
reset-gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
keyboard_pins_col: keyboard-matrix-col-pins {
|
||||
pins = "gpio8", "gpio9", "gpio10", "gpio11",
|
||||
"gpio12", "gpio13", "gpio14", "gpio15";
|
||||
function = "gpio";
|
||||
output-low;
|
||||
};
|
||||
keyboard_pins_row: keyboard-matrix-row-pins {
|
||||
pins = "gpio0", "gpio1", "gpio2", "gpio3",
|
||||
"gpio4", "gpio5", "gpio6", "gpio7";
|
||||
function = "gpio";
|
||||
drive-open-drain;
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp2_i2c1 {
|
||||
status = "ok";
|
||||
qcom,noise-reject-scl = <3>;
|
||||
qcom,noise-reject-sda = <3>;
|
||||
|
||||
touchscreen@14 {
|
||||
compatible = "goodix,gt9286";
|
||||
|
|
@ -208,6 +353,120 @@
|
|||
};
|
||||
};
|
||||
|
||||
&cpufreq_hw {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "ok";
|
||||
|
||||
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 = "ok";
|
||||
};
|
||||
|
||||
&dsi0_out {
|
||||
remote-endpoint = <&panel_in>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
};
|
||||
|
||||
&gcc {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&gpucc {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&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 = "ok";
|
||||
};
|
||||
|
||||
&mdss_mdp {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&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";
|
||||
};
|
||||
|
||||
&mmcc {
|
||||
status = "ok";
|
||||
};
|
||||
|
|
@ -216,7 +475,35 @@
|
|||
status = "ok";
|
||||
};
|
||||
|
||||
&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 {
|
||||
pins = "gpio5";
|
||||
function = "normal";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
|
||||
};
|
||||
|
||||
vol_up_pin_a: vol-up-active {
|
||||
pins = "gpio6";
|
||||
function = "normal";
|
||||
|
|
@ -270,6 +557,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";
|
||||
|
|
@ -298,6 +605,13 @@
|
|||
bias-disable;
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
panel_reset_n: panel-rst-n {
|
||||
pins = "gpio94";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
&ufshc {
|
||||
|
|
|
|||
|
|
@ -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,6 +9,7 @@
|
|||
/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 "pm8998.dtsi"
|
||||
|
|
@ -32,6 +33,7 @@
|
|||
height = <1920>;
|
||||
stride = <(1080 * 4)>;
|
||||
format = "a8r8g8b8";
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -152,10 +154,18 @@
|
|||
reg = <0x0 0x95715000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
&apc_cprh {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&cpufreq_hw {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&blsp1_i2c5 {
|
||||
status = "okay";
|
||||
|
||||
touchscreen@20 {
|
||||
rmi4_i2c: touchscreen@20 {
|
||||
compatible = "syna,rmi4-i2c";
|
||||
reg = <0x20>;
|
||||
#address-cells = <1>;
|
||||
|
|
@ -188,6 +198,31 @@
|
|||
};
|
||||
};
|
||||
|
||||
&blsp1_i2c5_sleep {
|
||||
/delete-property/ bias-pull-up;
|
||||
/* Configure a no-pull on TP I2C sleep to match downstream. */
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
&blsp1_i2c6 {
|
||||
status = "okay";
|
||||
|
||||
nfc: pn544@28 {
|
||||
compatible = "nxp,nxp-nci-i2c";
|
||||
reg = <0x28>;
|
||||
clock-frequency = <400000>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <92 IRQ_TYPE_NONE>;
|
||||
|
||||
enable-gpios = <&tlmm 116 0>;
|
||||
firmware-gpios = <&tlmm 93 0>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&nfc_int_active &nfc_enable_active>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_uart3 {
|
||||
status = "okay";
|
||||
|
||||
|
|
@ -224,10 +259,35 @@
|
|||
};
|
||||
};
|
||||
|
||||
&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_lsid1 {
|
||||
pm8005-regulators {
|
||||
compatible = "qcom,pm8005-regulators";
|
||||
|
|
@ -257,6 +317,49 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pmi8998_fg {
|
||||
status = "okay";
|
||||
|
||||
qcom,max-voltage-uv = <4370000>;
|
||||
qcom,min-voltage-uv = <3700000>;
|
||||
qcom,battery-capacity-ua = <3300000>;
|
||||
};
|
||||
|
||||
&pmi8998_lpg {
|
||||
status = "okay";
|
||||
|
||||
//qcom,power-source = <0>;
|
||||
|
||||
notification-led {
|
||||
color = <LED_COLOR_ID_RGB>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
|
||||
led@4 {
|
||||
reg = <4>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
};
|
||||
|
||||
led@5 {
|
||||
reg = <5>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pmi8998_haptics {
|
||||
status = "okay";
|
||||
|
||||
qcom,wave-play-rate-us = <4255>;
|
||||
};
|
||||
|
||||
&qusb2phy {
|
||||
status = "okay";
|
||||
|
||||
|
|
@ -437,9 +540,145 @@
|
|||
};
|
||||
};
|
||||
|
||||
&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";
|
||||
};
|
||||
|
||||
&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 {
|
||||
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 = "ok";
|
||||
};
|
||||
|
||||
&gpu_mem {
|
||||
compatible = "shared-dma-pool";
|
||||
};
|
||||
|
||||
&adreno_gpu {
|
||||
status = "ok";
|
||||
|
||||
zap-shader {
|
||||
memory-region = <&zap_shader_region>; // gpu_mem?
|
||||
firmware-name = "qcom/msm8998/oneplus/a540_zap.mbn";
|
||||
};
|
||||
|
||||
/*
|
||||
* We are lacking support for the GPU regulator. Hence, disable higher
|
||||
* frequencies for now to prevent the platform from hanging on high
|
||||
* graphics loads. Perhaps the pm8005_s1 voltage below could be
|
||||
* adjusted but I'd rather not touch it.
|
||||
*/
|
||||
opp-table {
|
||||
/delete-node/ opp-710000097;
|
||||
/delete-node/ opp-670000048;
|
||||
/delete-node/ opp-596000097;
|
||||
/delete-node/ opp-515000097;
|
||||
};
|
||||
};
|
||||
|
||||
&adreno_smmu {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
/*
|
||||
* 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";
|
||||
|
|
@ -461,6 +700,20 @@
|
|||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
nfc_int_active: nfc_int_active {
|
||||
pins = "gpio92";
|
||||
function = "gpio";
|
||||
drive-strength = <6>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
nfc_enable_active: nfc_enable_active {
|
||||
pins = "gpio12", "gpio116";
|
||||
function = "gpio";
|
||||
drive-strength = <6>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
&ufshc {
|
||||
|
|
@ -502,7 +755,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 {
|
||||
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 {
|
||||
regulator-min-microvolt = <2850000>;
|
||||
regulator-max-microvolt = <2850000>;
|
||||
|
|
|
|||
|
|
@ -20,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 {
|
||||
compatible = "simple-bus";
|
||||
|
||||
|
|
@ -84,6 +88,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";
|
||||
|
|
@ -186,11 +199,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>;
|
||||
|
|
@ -243,10 +273,79 @@
|
|||
};
|
||||
};
|
||||
|
||||
&blsp2_i2c1 {
|
||||
tof-sensor@29 {
|
||||
compatible = "st,vl53l0x";
|
||||
reg = <0x29>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
|
||||
#io-channel-cells = <1>;
|
||||
label = "back_camera_tof";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&tof_int_n &tof_rst_n>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp2_uart1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpufreq_hw {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
vdd-supply = <&vreg_l1a_0p875>;
|
||||
vdda-supply = <&vreg_l2a_1p2>;
|
||||
|
||||
panel: panel@0 {
|
||||
reg = <0>;
|
||||
|
||||
backlight = <&pmi8998_wled>;
|
||||
disp-te-gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
avdd-supply = <&lab>;
|
||||
avee-supply = <&ibb>;
|
||||
vddio-supply = <&vreg_l14a_1p85>;
|
||||
tavdd-supply = <&vreg_l28_3p0>;
|
||||
tvddio-supply = <&touch_vddio_vreg>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&panel_reset_n &mdp_vsync_n>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
panel_in0: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&dsi0_out {
|
||||
remote-endpoint = <&panel_in0>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
};
|
||||
|
||||
&dsi0_phy {
|
||||
status = "okay";
|
||||
vdds-supply = <&vreg_l1a_0p875>;
|
||||
};
|
||||
|
||||
&gpucc {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&ibb {
|
||||
regulator-min-microamp = <800000>;
|
||||
regulator-max-microamp = <800000>;
|
||||
|
|
@ -272,6 +371,25 @@
|
|||
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";
|
||||
};
|
||||
|
||||
&mmcc {
|
||||
status = "ok";
|
||||
};
|
||||
|
|
@ -288,7 +406,12 @@
|
|||
|
||||
/* 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>;
|
||||
regulator-always-on;
|
||||
|
|
@ -326,6 +449,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 {
|
||||
|
|
@ -360,6 +490,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";
|
||||
|
||||
|
|
@ -367,6 +528,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";
|
||||
|
|
@ -555,6 +729,371 @@
|
|||
pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
|
||||
};
|
||||
|
||||
/* 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>;
|
||||
|
||||
|
|
@ -608,6 +1147,14 @@
|
|||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
tof_int_n: tof-int-n {
|
||||
pins = "gpio22";
|
||||
function = "gpio";
|
||||
bias-pull-up;
|
||||
drive-strength = <2>;
|
||||
input-enable;
|
||||
};
|
||||
|
||||
cam1_vdig_default: cam1-vdig-default {
|
||||
pins = "gpio25";
|
||||
function = "gpio";
|
||||
|
|
@ -615,6 +1162,74 @@
|
|||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
tof_rst_n: tof-rst-n {
|
||||
pins = "gpio27";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
output-low;
|
||||
};
|
||||
|
||||
cam1_rst_default: cam1-rst-n {
|
||||
pins = "gpio28";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
cam0_rst_default: cam0-rst-n {
|
||||
pins = "gpio30";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
wcd_int_n: wcd-int-n {
|
||||
pins = "gpio54";
|
||||
function = "gpio";
|
||||
bias-pull-down;
|
||||
drive-strength = <2>;
|
||||
input-enable;
|
||||
};
|
||||
|
||||
cdc_reset_n: cdc-reset-n {
|
||||
pins = "gpio64";
|
||||
function = "gpio";
|
||||
bias-pull-down;
|
||||
drive-strength = <16>;
|
||||
output-high;
|
||||
};
|
||||
|
||||
wsa_leftspk_pwr_n: wsa-leftspk-pwr-n {
|
||||
pins = "gpio65";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
output-low;
|
||||
};
|
||||
|
||||
wsa_rightspk_pwr_n: wsa-rightspk-pwr-n {
|
||||
pins = "gpio66";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
output-low;
|
||||
};
|
||||
|
||||
ts_reset_n: ts-reset-n {
|
||||
pins = "gpio89";
|
||||
function = "gpio";
|
||||
bias-pull-up;
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
panel_reset_n: panel-rst-n {
|
||||
pins = "gpio94";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
hall_sensor0_default: acc-cover-open {
|
||||
pins = "gpio124";
|
||||
function = "gpio";
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -65,6 +65,15 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pm660l_lpg: lpg@b100 {
|
||||
compatible = "qcom,pm660l-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pm660l_wled: leds@d800 {
|
||||
compatible = "qcom,pm660l-wled";
|
||||
reg = <0xd800 0xd900>;
|
||||
|
|
|
|||
|
|
@ -125,6 +125,14 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pm8916_pwm: pwm {
|
||||
compatible = "qcom,pm8916-pwm";
|
||||
|
||||
#pwm-cells = <2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pm8916_vib: vibrator@c000 {
|
||||
compatible = "qcom,pm8916-vib";
|
||||
reg = <0xc000>;
|
||||
|
|
|
|||
|
|
@ -135,6 +135,16 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pm8994_lpg: lpg {
|
||||
compatible = "qcom,pm8994-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#pwm-cells = <2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pm8994_spmi_regulators: regulators {
|
||||
compatible = "qcom,pm8994-regulators";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -19,6 +19,29 @@
|
|||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pmi8994_fg: fuel_gauge@4000 {
|
||||
compatible = "qcom,pmi8994-fg";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
//FG //Charger
|
||||
reg = <0x4000 0x1000>;
|
||||
interrupts = <0x2 0x44 0x0 IRQ_TYPE_EDGE_BOTH>;
|
||||
interrupt-names = "mem-avail";
|
||||
};
|
||||
|
||||
pmi8994_mpps: mpps@a000 {
|
||||
compatible = "qcom,pmi8994-mpp";
|
||||
reg = <0xa000>;
|
||||
gpio-controller;
|
||||
gpio-ranges = <&pmi8994_mpps 0 0 4>;
|
||||
#gpio-cells = <2>;
|
||||
interrupts = <0 0xa0 0 IRQ_TYPE_NONE>,
|
||||
<0 0xa1 0 IRQ_TYPE_NONE>,
|
||||
<0 0xa2 0 IRQ_TYPE_NONE>,
|
||||
<0 0xa3 0 IRQ_TYPE_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
pmic@3 {
|
||||
|
|
@ -27,6 +50,16 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmi8994_lpg: lpg {
|
||||
compatible = "qcom,pmi8994-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#pwm-cells = <2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pmi8994_spmi_regulators: regulators {
|
||||
compatible = "qcom,pmi8994-regulators";
|
||||
#address-cells = <1>;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <dt-bindings/input/qcom,spmi-haptics.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/spmi/spmi.h>
|
||||
|
||||
|
|
@ -18,6 +19,17 @@
|
|||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pmi8998_fg: fuel_guage {
|
||||
compatible = "qcom,pmi8998-fg";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
//FG //Charger
|
||||
reg = <0x4000 0x1000>;
|
||||
interrupts = <0x2 0x13 0x4 IRQ_TYPE_EDGE_BOTH>;
|
||||
interrupt-names = "usb-plugin";
|
||||
};
|
||||
};
|
||||
|
||||
pmi8998_lsid1: pmic@3 {
|
||||
|
|
@ -53,5 +65,29 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
pmi8998_lpg: lpg {
|
||||
compatible = "qcom,pmi8998-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#pwm-cells = <2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pmi8998_haptics: haptics@c000 {
|
||||
compatible = "qcom,pmi8998-haptics", "qcom,spmi-haptics";
|
||||
reg = <0xc000>;
|
||||
|
||||
interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
|
||||
<0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
|
||||
interrupt-names = "short", "play";
|
||||
|
||||
qcom,wave-shape = <HAP_WAVE_SINE>;
|
||||
qcom,play-mode = <HAP_PLAY_BUFFER>;
|
||||
qcom,brake-pattern = <0x3 0x3 0x2 0x1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1173,19 +1173,19 @@
|
|||
<&cpr_efuse_ring2>,
|
||||
<&cpr_efuse_ring3>,
|
||||
<&cpr_efuse_revision>;
|
||||
nvmem-cell-names = "cpr_quotient_offset1",
|
||||
"cpr_quotient_offset2",
|
||||
"cpr_quotient_offset3",
|
||||
"cpr_init_voltage1",
|
||||
"cpr_init_voltage2",
|
||||
"cpr_init_voltage3",
|
||||
"cpr_quotient1",
|
||||
"cpr_quotient2",
|
||||
"cpr_quotient3",
|
||||
"cpr_ring_osc1",
|
||||
"cpr_ring_osc2",
|
||||
"cpr_ring_osc3",
|
||||
"cpr_fuse_revision";
|
||||
nvmem-cell-names = "cpr0_quotient_offset1",
|
||||
"cpr0_quotient_offset2",
|
||||
"cpr0_quotient_offset3",
|
||||
"cpr0_init_voltage1",
|
||||
"cpr0_init_voltage2",
|
||||
"cpr0_init_voltage3",
|
||||
"cpr0_quotient1",
|
||||
"cpr0_quotient2",
|
||||
"cpr0_quotient3",
|
||||
"cpr0_ring_osc1",
|
||||
"cpr0_ring_osc2",
|
||||
"cpr0_ring_osc3",
|
||||
"cpr0_fuse_revision";
|
||||
};
|
||||
|
||||
timer@b120000 {
|
||||
|
|
|
|||
|
|
@ -23,4 +23,9 @@
|
|||
|
||||
/* Ganges devices feature a Novatek touchscreen instead. */
|
||||
/delete-node/ &touchscreen;
|
||||
|
||||
&panel {
|
||||
compatible = "sony,kirin-nt36672a-truly";
|
||||
};
|
||||
|
||||
/delete-node/ &vreg_l18a_1v8;
|
||||
|
|
|
|||
|
|
@ -13,3 +13,7 @@
|
|||
compatible = "sony,discovery-row", "qcom,sdm630";
|
||||
chassis-type = "handset";
|
||||
};
|
||||
|
||||
&panel {
|
||||
compatible = "sony,discovery-td4322-innolux";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,3 +13,7 @@
|
|||
compatible = "sony,pioneer-row", "qcom,sdm630";
|
||||
chassis-type = "handset";
|
||||
};
|
||||
|
||||
&panel {
|
||||
compatible = "sony,pioneer-td4322-truly";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,3 +20,7 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
&panel {
|
||||
compatible = "sony,voyager-td4328-tianma";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/input/gpio-keys.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
/* required for bootloader to select correct board */
|
||||
|
|
@ -19,23 +20,23 @@
|
|||
|
||||
/* This part enables graphical output via bootloader-enabled display */
|
||||
chosen {
|
||||
bootargs = "earlycon=tty0 console=tty0";
|
||||
// bootargs = "earlycon=tty0 console=tty0";
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
stdout-path = "framebuffer0";
|
||||
// stdout-path = "framebuffer0";
|
||||
|
||||
framebuffer0: framebuffer@9d400000 {
|
||||
compatible = "simple-framebuffer";
|
||||
reg = <0 0x9d400000 0 (1920 * 1080 * 4)>;
|
||||
width = <1080>;
|
||||
height = <1920>;
|
||||
stride = <(1080 * 4)>;
|
||||
format = "a8r8g8b8";
|
||||
status= "okay";
|
||||
};
|
||||
// framebuffer0: framebuffer@9d400000 {
|
||||
// compatible = "simple-framebuffer";
|
||||
// reg = <0 0x9d400000 0 (1920 * 1080 * 4)>;
|
||||
// width = <1080>;
|
||||
// height = <1920>;
|
||||
// stride = <(1080 * 4)>;
|
||||
// format = "a8r8g8b8";
|
||||
// status= "okay";
|
||||
// };
|
||||
};
|
||||
|
||||
board_vbat: vbat-regulator {
|
||||
|
|
@ -212,7 +213,92 @@
|
|||
&blsp2_uart1 {
|
||||
status = "okay";
|
||||
|
||||
/* HCI Bluetooth */
|
||||
bluetooth: wcn3990-bt {
|
||||
compatible = "qcom,wcn3998-bt";
|
||||
|
||||
vddio-supply = <&vreg_l13a_1p8>;
|
||||
vddxo-suppky = <&vreg_l9a_1p8>;
|
||||
vddrf-supply = <&vreg_l6a_1p3>;
|
||||
vddch0-supply = <&vreg_l19a_3p3>;
|
||||
|
||||
max-speed = <3200000>;
|
||||
|
||||
clocks = <&rpmcc RPM_SMD_RF_CLK1_PIN>;
|
||||
};
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
vdda-supply = <&vreg_l1a_1p225>;
|
||||
|
||||
panel: panel@0 {
|
||||
reg = <0>;
|
||||
|
||||
reset-gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>;
|
||||
disp-te-gpios = <&tlmm 59 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
backlight = <&pm660l_wled>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&panel_reset_n &mdp_vsync_n>;
|
||||
port {
|
||||
panel_in: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&dsi0_out {
|
||||
remote-endpoint = <&panel_in>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
};
|
||||
|
||||
&mdss {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pm660l_lpg {
|
||||
// No idea, and optional...
|
||||
// qcom,power-source = <1>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
multi-led {
|
||||
color = <LED_COLOR_ID_RGB>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pm660l_wled {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpucc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pon {
|
||||
|
|
@ -564,7 +650,7 @@
|
|||
};
|
||||
|
||||
&sdhc_2 {
|
||||
status = "okay";
|
||||
status = "disabled";
|
||||
|
||||
vmmc-supply = <&vreg_l5b_2p95>;
|
||||
vqmmc-supply = <&vreg_l2b_2p95>;
|
||||
|
|
@ -605,6 +691,20 @@
|
|||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
panel_reset_n: panel-rst-n {
|
||||
pins = "gpio53";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
mdp_vsync_n: mdp-vsync-n {
|
||||
pins = "gpio59";
|
||||
function = "mdp_vsync";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
&usb3 {
|
||||
|
|
@ -615,3 +715,345 @@
|
|||
dr_mode = "peripheral";
|
||||
extcon = <&extcon_usb>;
|
||||
};
|
||||
|
||||
&rpm_requests {
|
||||
pm660l-regulators {
|
||||
compatible = "qcom,rpm-pm660l-regulators";
|
||||
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
vdd_s2-supply = <&vph_pwr>;
|
||||
vdd_s3_s4-supply = <&vph_pwr>;
|
||||
vdd_s5-supply = <&vph_pwr>;
|
||||
vdd_s6-supply = <&vph_pwr>;
|
||||
|
||||
vdd_l1_l9_l10-supply = <&vreg_s2b_1p05>;
|
||||
vdd_l2-supply = <&vreg_bob>;
|
||||
vdd_l3_l5_l7_l8-supply = <&vreg_bob>;
|
||||
vdd_l4_l6-supply = <&vreg_bob>;
|
||||
vdd_bob-supply = <&vph_pwr>;
|
||||
|
||||
vreg_s1b_1p125: s1 {
|
||||
regulator-min-microvolt = <1125000>;
|
||||
regulator-max-microvolt = <1125000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_s2b_1p05: s2 {
|
||||
regulator-min-microvolt = <1050000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/*
|
||||
* At least on Nile's configuration, S3B/S4B (VDD_CX) and
|
||||
* S5B (VDD_MX) are managed only through RPM Power Domains.
|
||||
* Trying to set a voltage on the main supply will create
|
||||
* havoc and freeze the SoC.
|
||||
* In any case, reference voltages for these regulators are:
|
||||
* S3B/S4B: 0.870V
|
||||
* S5B: 0.915V
|
||||
*/
|
||||
|
||||
/* LDOs */
|
||||
vreg_l1b_0p925: l1 {
|
||||
regulator-min-microvolt = <920000>;
|
||||
regulator-max-microvolt = <928000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l2b_2p95: l2 {
|
||||
/*
|
||||
* This regulator supports 1.648 - 3.104V on this board
|
||||
* but we set a max voltage of anything less than 2.7V
|
||||
* to satisfy a condition in sdhci.c that will disable
|
||||
* 3.3V SDHCI signaling, which happens to be not really
|
||||
* supported on the Xperia Nile/Ganges platform.
|
||||
*/
|
||||
regulator-min-microvolt = <1648000>;
|
||||
regulator-max-microvolt = <2696000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l3b_3p0: l3 {
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-min-microamp = <200>;
|
||||
regulator-max-microamp = <600000>;
|
||||
regulator-system-load = <100000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l4b_29p5: l4 {
|
||||
regulator-min-microvolt = <2944000>;
|
||||
regulator-max-microvolt = <2952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
|
||||
regulator-min-microamp = <200>;
|
||||
regulator-max-microamp = <600000>;
|
||||
regulator-system-load = <570000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
/*
|
||||
* Downstream specifies a range of 1721-3600mV,
|
||||
* but the only assigned consumers are SDHCI2 VMMC
|
||||
* and Coresight QPDI that both request pinned 2.95V.
|
||||
* Tighten the range to 1.8-3.328 (closest to 3.3) to
|
||||
* make the mmc driver happy.
|
||||
*/
|
||||
vreg_l5b_29p5: l5 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3328000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l6b_3p3: l6 {
|
||||
regulator-min-microvolt = <1704000>;
|
||||
regulator-max-microvolt = <3312000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l7b_3p125: l7 {
|
||||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <3128000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l8b_3p3: l8 {
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/* L9B (870mV) is currently unused */
|
||||
/* L10B (915mV) is currently unused */
|
||||
|
||||
vreg_bob: bob {
|
||||
regulator-min-microvolt = <3304000>;
|
||||
regulator-max-microvolt = <3624000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
pm660-regulators {
|
||||
compatible = "qcom,rpm-pm660-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_l1_l6_l7-supply = <&vreg_s5a_1p35>;
|
||||
vdd_l2_l3-supply = <&vreg_s2b_1p05>;
|
||||
vdd_l5-supply = <&vreg_s2b_1p05>;
|
||||
vdd_l8_l9_l10_l11_l12_l13_l14-supply = <&vreg_s4a_2p04>;
|
||||
vdd_l15_l16_l17_l18_l19-supply = <&vreg_bob>;
|
||||
|
||||
/*
|
||||
* S1A (FTAPC0), S2A (FTAPC1), S3A (HFAPC1) are managed
|
||||
* by the Core Power Reduction hardened (CPRh) and the
|
||||
* Operating State Manager (OSM) HW automatically.
|
||||
*/
|
||||
|
||||
vreg_s4a_2p04: s4 {
|
||||
regulator-min-microvolt = <2040000>;
|
||||
regulator-max-microvolt = <2040000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vreg_s5a_1p35: s5 {
|
||||
regulator-min-microvolt = <1224000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_s6a_0p87: s6 {
|
||||
regulator-min-microvolt = <504000>;
|
||||
regulator-max-microvolt = <992000>;
|
||||
regulator-enable-ramp-delay = <150>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/* LDOs */
|
||||
vreg_l1a_1p225: l1 {
|
||||
regulator-min-microvolt = <1226000>;
|
||||
regulator-max-microvolt = <1250000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l2a_1p0: l2 {
|
||||
regulator-min-microvolt = <944000>;
|
||||
regulator-max-microvolt = <1008000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l3a_1p0: l3 {
|
||||
regulator-min-microvolt = <944000>;
|
||||
regulator-max-microvolt = <1008000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l5a_0p848: l5 {
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l6a_1p3: l6 {
|
||||
regulator-min-microvolt = <1304000>;
|
||||
regulator-max-microvolt = <1368000>;
|
||||
regulator-allow-set-load;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l7a_1p2: l7 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l8a_1p8: l8 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-system-load = <325000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
|
||||
vreg_l9a_1p8: l9 {
|
||||
regulator-min-microvolt = <1804000>;
|
||||
regulator-max-microvolt = <1896000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l10a_1p8: l10 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1944000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l11a_1p8: l11 {
|
||||
regulator-min-microvolt = <1784000>;
|
||||
regulator-max-microvolt = <1944000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l12a_1p8: l12 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1944000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/* This gives power to the LPDDR4: never turn it off! */
|
||||
vreg_l13a_1p8: l13 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1944000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vreg_l14a_1p8: l14 {
|
||||
regulator-min-microvolt = <1710000>;
|
||||
regulator-max-microvolt = <1904000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l15a_1p8: l15 {
|
||||
regulator-min-microvolt = <1648000>;
|
||||
regulator-max-microvolt = <2952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/* L16A (2.70V) is unused */
|
||||
|
||||
vreg_l17a_1p8: l17 {
|
||||
regulator-min-microvolt = <1648000>;
|
||||
regulator-max-microvolt = <2952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l18a_1v8: l18 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <10>;
|
||||
regulator-min-microamp = <200>;
|
||||
regulator-max-microamp = <50000>;
|
||||
regulator-system-load = <10000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l19a_3p3: l19 {
|
||||
regulator-min-microvolt = <3312000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
gpio-reserved-ranges = <8 4>;
|
||||
|
||||
imx300_vana_default: imx300-vana-default {
|
||||
pins = "gpio50";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
imx219_vana_default: imx219-vana-default {
|
||||
pins = "gpio51";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
cam_vdig_default: cam-vdig-default {
|
||||
pins = "gpio52";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@
|
|||
&PERF_CLUSTER_SLEEP_1
|
||||
&PERF_CLUSTER_SLEEP_2>;
|
||||
capacity-dmips-mhz = <1126>;
|
||||
dynamic-power-coefficient = <118>;
|
||||
operating-points-v2 = <&cpu_gold_opp_table>;
|
||||
power-domains = <&apc_cprh 0>;
|
||||
power-domain-names = "cprh";
|
||||
clocks = <&xo_board>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_1>;
|
||||
L2_1: l2-cache {
|
||||
|
|
@ -71,6 +77,12 @@
|
|||
&PERF_CLUSTER_SLEEP_1
|
||||
&PERF_CLUSTER_SLEEP_2>;
|
||||
capacity-dmips-mhz = <1126>;
|
||||
dynamic-power-coefficient = <118>;
|
||||
operating-points-v2 = <&cpu_gold_opp_table>;
|
||||
power-domains = <&apc_cprh 0>;
|
||||
power-domain-names = "cprh";
|
||||
clocks = <&xo_board>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_1>;
|
||||
};
|
||||
|
|
@ -86,6 +98,12 @@
|
|||
&PERF_CLUSTER_SLEEP_1
|
||||
&PERF_CLUSTER_SLEEP_2>;
|
||||
capacity-dmips-mhz = <1126>;
|
||||
dynamic-power-coefficient = <118>;
|
||||
operating-points-v2 = <&cpu_gold_opp_table>;
|
||||
power-domains = <&apc_cprh 0>;
|
||||
power-domain-names = "cprh";
|
||||
clocks = <&xo_board>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_1>;
|
||||
};
|
||||
|
|
@ -101,6 +119,12 @@
|
|||
&PERF_CLUSTER_SLEEP_1
|
||||
&PERF_CLUSTER_SLEEP_2>;
|
||||
capacity-dmips-mhz = <1126>;
|
||||
dynamic-power-coefficient = <118>;
|
||||
operating-points-v2 = <&cpu_gold_opp_table>;
|
||||
power-domains = <&apc_cprh 0>;
|
||||
power-domain-names = "cprh";
|
||||
clocks = <&xo_board>;
|
||||
qcom,freq-domain = <&cpufreq_hw 1>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_1>;
|
||||
};
|
||||
|
|
@ -116,6 +140,12 @@
|
|||
&PWR_CLUSTER_SLEEP_1
|
||||
&PWR_CLUSTER_SLEEP_2>;
|
||||
capacity-dmips-mhz = <1024>;
|
||||
dynamic-power-coefficient = <100>;
|
||||
operating-points-v2 = <&cpu_silver_opp_table>;
|
||||
power-domains = <&apc_cprh 1>;
|
||||
power-domain-names = "cprh";
|
||||
clocks = <&xo_board>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_0>;
|
||||
L2_0: l2-cache {
|
||||
|
|
@ -135,6 +165,12 @@
|
|||
&PWR_CLUSTER_SLEEP_1
|
||||
&PWR_CLUSTER_SLEEP_2>;
|
||||
capacity-dmips-mhz = <1024>;
|
||||
dynamic-power-coefficient = <100>;
|
||||
operating-points-v2 = <&cpu_silver_opp_table>;
|
||||
power-domains = <&apc_cprh 1>;
|
||||
power-domain-names = "cprh";
|
||||
clocks = <&xo_board>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_0>;
|
||||
};
|
||||
|
|
@ -150,6 +186,12 @@
|
|||
&PWR_CLUSTER_SLEEP_1
|
||||
&PWR_CLUSTER_SLEEP_2>;
|
||||
capacity-dmips-mhz = <1024>;
|
||||
dynamic-power-coefficient = <100>;
|
||||
operating-points-v2 = <&cpu_silver_opp_table>;
|
||||
power-domains = <&apc_cprh 1>;
|
||||
power-domain-names = "cprh";
|
||||
clocks = <&xo_board>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_0>;
|
||||
};
|
||||
|
|
@ -165,6 +207,12 @@
|
|||
&PWR_CLUSTER_SLEEP_1
|
||||
&PWR_CLUSTER_SLEEP_2>;
|
||||
capacity-dmips-mhz = <1024>;
|
||||
dynamic-power-coefficient = <100>;
|
||||
operating-points-v2 = <&cpu_silver_opp_table>;
|
||||
power-domains = <&apc_cprh 1>;
|
||||
power-domain-names = "cprh";
|
||||
clocks = <&xo_board>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_0>;
|
||||
};
|
||||
|
|
@ -204,6 +252,7 @@
|
|||
core3 {
|
||||
cpu = <&CPU3>;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -314,6 +363,28 @@
|
|||
scm {
|
||||
compatible = "qcom,scm-msm8998", "qcom,scm";
|
||||
};
|
||||
android {
|
||||
compatible = "android,firmware";
|
||||
fstab {
|
||||
compatible = "android,fstab";
|
||||
vendor {
|
||||
compatible = "android,vendor";
|
||||
dev = "/dev/block/platform/soc/c0c4000.sdhci/by-name/vendor_a";
|
||||
type = "ext4";
|
||||
mnt_flags = "ro,barrier=1,discard";
|
||||
fsmgr_flags = "wait";
|
||||
status = "ok";
|
||||
};
|
||||
system {
|
||||
compatible = "android,system";
|
||||
dev = "/dev/block/platform/soc/c0c4000.sdhci/by-name/system_a";
|
||||
type = "ext4";
|
||||
mnt_flags = "ro,barrier=1,discard";
|
||||
fsmgr_flags = "wait";
|
||||
status = "ok";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
memory@80000000 {
|
||||
|
|
@ -332,6 +403,175 @@
|
|||
method = "smc";
|
||||
};
|
||||
|
||||
cpu_silver_opp_table: cpu-silver-opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp-1843200000 {
|
||||
opp-hz = /bits/ 64 <1843200000>;
|
||||
required-opps = <&cprh_opp8>;
|
||||
qcom,pll-override = <0x094c004c>;
|
||||
qcom,spare-data = <3>;
|
||||
};
|
||||
opp-1728000000 {
|
||||
opp-hz = /bits/ 64 <1728000000>;
|
||||
required-opps = <&cprh_opp7>;
|
||||
qcom,pll-override = <0x09480048>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-1536000000 {
|
||||
opp-hz = /bits/ 64 <1536000000>;
|
||||
required-opps = <&cprh_opp6>;
|
||||
qcom,pll-override = <0x08400040>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-1382400000 {
|
||||
opp-hz = /bits/ 64 <1382400000>;
|
||||
required-opps = <&cprh_opp5>;
|
||||
qcom,pll-override = <0x07390039>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-1094400000 {
|
||||
opp-hz = /bits/ 64 <1094400000>;
|
||||
required-opps = <&cprh_opp4>;
|
||||
qcom,pll-override = <0x052e002e>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-883200000 {
|
||||
opp-hz = /bits/ 64 <883200000>;
|
||||
required-opps = <&cprh_opp3>;
|
||||
qcom,pll-override = <0x04250025>;
|
||||
qcom,spare-data = <1>;
|
||||
};
|
||||
opp-614400000 {
|
||||
opp-hz = /bits/ 64 <614400000>;
|
||||
required-opps = <&cprh_opp2>;
|
||||
qcom,pll-override = <0x3200020>;
|
||||
qcom,pll-div = <1>;
|
||||
qcom,spare-data = <1>;
|
||||
};
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&cprh_opp1>;
|
||||
qcom,pll-override = <0x1200020>;
|
||||
qcom,spare-data = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu_gold_opp_table: cpu-gold-opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp-2208000000 {
|
||||
opp-hz = /bits/ 64 <2208000000>;
|
||||
required-opps = <&cprh_opp10>;
|
||||
qcom,pll-override = <0x0b5c005c>;
|
||||
qcom,spare-data = <3>;
|
||||
};
|
||||
opp-2150400000 {
|
||||
opp-hz = /bits/ 64 <2150400000>;
|
||||
required-opps = <&cprh_opp9>;
|
||||
qcom,pll-override = <0x0b590059>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-2016000000 {
|
||||
opp-hz = /bits/ 64 <2016000000>;
|
||||
required-opps = <&cprh_opp8>;
|
||||
qcom,pll-override = <0x0a540054>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-1881600000 {
|
||||
opp-hz = /bits/ 64 <1881600000>;
|
||||
required-opps = <&cprh_opp7>;
|
||||
qcom,pll-override = <0x094e004e>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-1670400000 {
|
||||
opp-hz = /bits/ 64 <1670400000>;
|
||||
required-opps = <&cprh_opp6>;
|
||||
qcom,pll-override = <0x08450045>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-1516800000 {
|
||||
opp-hz = /bits/ 64 <1516800000>;
|
||||
required-opps = <&cprh_opp5>;
|
||||
qcom,pll-override = <0x073f003f>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-1344000000 {
|
||||
opp-hz = /bits/ 64 <1344000000>;
|
||||
required-opps = <&cprh_opp4>;
|
||||
qcom,pll-override = <0x07380038>;
|
||||
qcom,spare-data = <2>;
|
||||
|
||||
};
|
||||
opp-1113600000 {
|
||||
opp-hz = /bits/ 64 <1113600000>;
|
||||
required-opps = <&cprh_opp3>;
|
||||
qcom,pll-override = <0x052e002e>;
|
||||
qcom,spare-data = <2>;
|
||||
};
|
||||
opp-787200000 {
|
||||
opp-hz = /bits/ 64 <787200000>;
|
||||
required-opps = <&cprh_opp2>;
|
||||
qcom,pll-override = <0x4200020>;
|
||||
qcom,pll-div = <1>;
|
||||
qcom,spare-data = <1>;
|
||||
};
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&cprh_opp1>;
|
||||
qcom,pll-override = <0x1200020>;
|
||||
qcom,spare-data = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
cprh_opp_table: cpr-gold-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 = <1>;
|
||||
};
|
||||
cprh_opp3: opp3 {
|
||||
opp-level = <3>;
|
||||
qcom,opp-fuse-level = <2>;
|
||||
};
|
||||
cprh_opp4: opp4 {
|
||||
opp-level = <4>;
|
||||
qcom,opp-fuse-level = <2>;
|
||||
};
|
||||
cprh_opp5: opp5 {
|
||||
opp-level = <5>;
|
||||
qcom,opp-fuse-level = <3>;
|
||||
};
|
||||
cprh_opp6: opp6 {
|
||||
opp-level = <6>;
|
||||
qcom,opp-fuse-level = <3>;
|
||||
};
|
||||
cprh_opp7: opp7 {
|
||||
opp-level = <7>;
|
||||
qcom,opp-fuse-level = <4 3>;
|
||||
};
|
||||
cprh_opp8: opp8 {
|
||||
opp-level = <8>;
|
||||
qcom,opp-fuse-level = <4 3>;
|
||||
};
|
||||
cprh_opp9: opp9 {
|
||||
opp-level = <9>;
|
||||
qcom,opp-fuse-level = <4>;
|
||||
};
|
||||
cprh_opp10: opp10 {
|
||||
opp-level = <10>;
|
||||
qcom,opp-fuse-level = <5>;
|
||||
};
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
|
@ -552,14 +792,190 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
qusb2_hstx_trim: hstx-trim@240 {
|
||||
reg = <0x240 0x1>;
|
||||
bits = <25 3>;
|
||||
cpr_efuse_speedbin: speedbin@133 {
|
||||
reg = <0x133 0x8>;
|
||||
bits = <5 3>;
|
||||
};
|
||||
|
||||
gpu_speed_bin: gpu-speed-bin@41a0 {
|
||||
reg = <0x41a0 0x1>;
|
||||
bits = <21 7>;
|
||||
/* CPR Quotients: Power Cluster */
|
||||
cpr_quot00_pwrcl: quot00_pwrcl@221 {
|
||||
reg = <0x221 0x4>;
|
||||
bits = <4 12>;
|
||||
};
|
||||
|
||||
cpr_quot01_pwrcl: quot01_pwrcl@239 {
|
||||
reg = <0x239 0x4>;
|
||||
bits = <1 12>;
|
||||
};
|
||||
|
||||
cpr_quot02_pwrcl: quot02_pwrcl@21d {
|
||||
reg = <0x21d 0x4>;
|
||||
bits = <0 12>;
|
||||
};
|
||||
|
||||
cpr_quot_offset01_pwrcl: qoff01_pwrcl@23a {
|
||||
reg = <0x23a 0x4>;
|
||||
bits = <5 7>;
|
||||
};
|
||||
|
||||
cpr_quot_offset02_pwrcl: qoff02_pwrcl@223 {
|
||||
reg = <0x223 0x4>;
|
||||
bits = <0 7>;
|
||||
};
|
||||
|
||||
/* CPR Quotients: Performance Cluster */
|
||||
cpr_quot00_perfcl: quot00_perfcl@22e {
|
||||
reg = <0x22e 0x4>;
|
||||
bits = <5 11>;
|
||||
};
|
||||
|
||||
cpr_quot10_perfcl: quot10_perfcl@230 {
|
||||
reg = <0x230 0x4>;
|
||||
bits = <0 1>;
|
||||
};
|
||||
|
||||
cpr_quot01_perfcl: quot01_perfcl@230 {
|
||||
reg = <0x230 0x4>;
|
||||
bits = <1 12>;
|
||||
};
|
||||
|
||||
cpr_quot02_perfcl: quot02_perfcl@22d {
|
||||
reg = <0x22d 0x4>;
|
||||
bits = <1 12>;
|
||||
};
|
||||
|
||||
cpr_quot03_perfcl: quot03_perfcl@22b {
|
||||
reg = <0x22b 0x8>;
|
||||
bits = <5 12>;
|
||||
};
|
||||
|
||||
cpr_quot04_perfcl: quot04_perfcl@23e {
|
||||
reg = <0x236 0x4>;
|
||||
bits = <0 12>;
|
||||
};
|
||||
|
||||
cpr_quot_offset01_perfcl: qoff01_perfcl@233 {
|
||||
reg = <0x233 0x4>;
|
||||
bits = <3 7>;
|
||||
};
|
||||
|
||||
cpr_quot_offset02_perfcl: qoff02_perfcl@232 {
|
||||
reg = <0x232 0x4>;
|
||||
bits = <4 7>;
|
||||
};
|
||||
|
||||
cpr_quot_offset03_perfcl: qoff03_perfcl@231 {
|
||||
reg = <0x231 0x4>;
|
||||
bits = <5 7>;
|
||||
};
|
||||
|
||||
cpr_quot_offset04_perfcl: qoff04_perfcl@237 {
|
||||
reg = <0x237 0x4>;
|
||||
bits = <4 4>;
|
||||
};
|
||||
|
||||
cpr_quot_offset14_perfcl: qoff14_perfcl@230 {
|
||||
reg = <0x230 0x4>;
|
||||
bits = <0 3>;
|
||||
};
|
||||
|
||||
/* CPR Init Voltage: Power Cluster */
|
||||
cpr_init_voltage00_pwrcl: ivolt00_pwrcl@21c {
|
||||
reg = <0x21c 0x4>;
|
||||
bits = <2 6>;
|
||||
};
|
||||
|
||||
cpr_init_voltage01_pwrcl: ivolt01_pwrcl@238 {
|
||||
reg = <0x238 0x4>;
|
||||
bits = <3 6>;
|
||||
};
|
||||
|
||||
cpr_init_voltage02_pwrcl: ivolt02_pwrcl@219 {
|
||||
reg = <0x219 0x4>;
|
||||
bits = <8 6>;
|
||||
};
|
||||
|
||||
/* CPR Init Voltage: Performance Cluster */
|
||||
cpr_init_voltage00_perfcl: ivolt00_perfcl@22a {
|
||||
reg = <0x22a 0x4>;
|
||||
bits = <1 6>;
|
||||
};
|
||||
|
||||
cpr_init_voltage01_perfcl: ivolt01_perfcl@22a {
|
||||
reg = <0x22a 0x4>;
|
||||
bits = <7 6>;
|
||||
};
|
||||
|
||||
cpr_init_voltage02_perfcl: ivolt02_perfcl@229 {
|
||||
reg = <0x229 0x4>;
|
||||
bits = <3 6>;
|
||||
};
|
||||
|
||||
cpr_init_voltage03_perfcl: ivolt03_perfcl@228 {
|
||||
reg = <0x228 0x4>;
|
||||
bits = <5 6>;
|
||||
};
|
||||
|
||||
cpr_init_voltage04_perfcl: ivolt04_perfcl@235 {
|
||||
reg = <0x235 0x4>;
|
||||
bits = <2 6>;
|
||||
};
|
||||
|
||||
/* CPR Ring Oscillator: Power Cluster */
|
||||
cpr_ro_sel00_pwrcl: rosel00_pwrcl@219 {
|
||||
reg = <0x219 0x4>;
|
||||
bits = <4 4>;
|
||||
};
|
||||
|
||||
cpr_ro_sel01_pwrcl: rosel01_pwrcl@20f {
|
||||
reg = <0x20f 0x4>;
|
||||
bits = <0 4>;
|
||||
};
|
||||
|
||||
cpr_ro_sel02_pwrcl: rosel02_pwrcl@218 {
|
||||
reg = <0x218 0x4>;
|
||||
bits = <0 4>;
|
||||
};
|
||||
|
||||
/* CPR Ring Oscillator: Performance Cluster */
|
||||
cpr_ro_sel00_perfcl: rosel00_perfcl@227 {
|
||||
reg = <0x227 0x4>;
|
||||
bits = <5 4>;
|
||||
};
|
||||
|
||||
cpr_ro_sel01_perfcl: rosel01_perfcl@228 {
|
||||
reg = <0x228 0x4>;
|
||||
bits = <1 4>;
|
||||
};
|
||||
|
||||
cpr_ro_sel02_perfcl: rosel02_perfcl@227 {
|
||||
reg = <0x227 0x4>;
|
||||
bits = <1 4>;
|
||||
};
|
||||
|
||||
cpr_ro_sel03_perfcl: rosel03_perfcl@226 {
|
||||
reg = <0x226 0x4>;
|
||||
bits = <5 4>;
|
||||
};
|
||||
|
||||
cpr_ro_sel04_perfcl: rosel04_perfcl@211 {
|
||||
reg = <0x211 0x4>;
|
||||
bits = <6 4>;
|
||||
};
|
||||
|
||||
cpr_fuse_revision: cpr_fusing_rev@23b {
|
||||
reg = <0x23b 0x1>;
|
||||
bits = <4 3>;
|
||||
};
|
||||
|
||||
qusb2_hstx_trim: hstx-trim@243 {
|
||||
reg = <0x243 0x1>;
|
||||
bits = <1 3>;
|
||||
};
|
||||
|
||||
gpu_speed_bin: gpu_speed_bin@1a2 {
|
||||
reg = <0x1a2 0x1>;
|
||||
bits = <5 7>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -612,6 +1028,9 @@
|
|||
clock-names = "bus";
|
||||
#global-interrupts = <2>;
|
||||
#iommu-cells = <1>;
|
||||
qcom,bypass-cbndx = /bits/ 8 <6>;
|
||||
qcom,reset-nodisable-cbs = /bits/ 8 <7 8 9 10 11 12 13 14
|
||||
15 16 17 18 19 20>;
|
||||
|
||||
interrupts =
|
||||
<GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
|
||||
|
|
@ -646,8 +1065,6 @@
|
|||
<GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
a2noc: interconnect@1704000 {
|
||||
|
|
@ -680,6 +1097,114 @@
|
|||
<&mmcc AHB_CLK_SRC>;
|
||||
};
|
||||
|
||||
saw1: power-controller@17812000 {
|
||||
compatible = "qcom,sdm660-gold-saw2-v4.1-l2", "qcom,saw2";
|
||||
reg = <0x017812000 0x1000>;
|
||||
};
|
||||
|
||||
saw0: power-controller@17912000 {
|
||||
compatible = "qcom,sdm660-gold-saw2-v4.1-l2", "qcom,saw2";
|
||||
reg = <0x017912000 0x1000>;
|
||||
};
|
||||
|
||||
cpufreq_hw: cpufreq_hw@17816000 {
|
||||
compatible = "qcom,cpufreq-hw-8998";
|
||||
|
||||
reg = <0x0179c0000 0x1000>, <0x0179c1000 0x1000>,
|
||||
<0x0179c2000 0x1000>, <0x0179c3000 0x1000>;
|
||||
reg-names = "osm-domain0", "freq-domain0",
|
||||
"osm-domain1", "freq-domain1";
|
||||
|
||||
assigned-clocks = <&gcc HMSS_GPLL0_CLK_SRC>;
|
||||
assigned-clock-rates = <300000000>;
|
||||
|
||||
clocks = <&rpmcc RPM_SMD_XO_A_CLK_SRC>,
|
||||
<&gcc HMSS_GPLL0_CLK_SRC>;
|
||||
clock-names = "xo", "alternate";
|
||||
|
||||
#freq-domain-cells = <1>;
|
||||
};
|
||||
|
||||
/* Gold and Silver cluster */
|
||||
apc_cprh: power-controller@179c4000 {
|
||||
compatible = "qcom,sdm630-cprh";
|
||||
reg = <0x0179c4000 0x4000>, <0x0179c8000 0x4000>;
|
||||
|
||||
clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
|
||||
clock-names = "ref";
|
||||
assigned-clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
#power-domain-cells = <1>;
|
||||
operating-points-v2 = <&cprh_opp_table>;
|
||||
|
||||
nvmem-cells = <&cpr_efuse_speedbin>,
|
||||
<&cpr_fuse_revision>,
|
||||
<&cpr_quot00_perfcl>,
|
||||
<&cpr_quot01_perfcl>,
|
||||
<&cpr_quot02_perfcl>,
|
||||
<&cpr_quot03_perfcl>,
|
||||
<&cpr_quot04_perfcl>,
|
||||
<&cpr_quot_offset01_perfcl>,
|
||||
<&cpr_quot_offset02_perfcl>,
|
||||
<&cpr_quot_offset03_perfcl>,
|
||||
<&cpr_quot_offset04_perfcl>,
|
||||
<&cpr_init_voltage00_perfcl>,
|
||||
<&cpr_init_voltage01_perfcl>,
|
||||
<&cpr_init_voltage02_perfcl>,
|
||||
<&cpr_init_voltage03_perfcl>,
|
||||
<&cpr_init_voltage04_perfcl>,
|
||||
<&cpr_ro_sel00_perfcl>,
|
||||
<&cpr_ro_sel01_perfcl>,
|
||||
<&cpr_ro_sel02_perfcl>,
|
||||
<&cpr_ro_sel03_perfcl>,
|
||||
<&cpr_ro_sel04_perfcl>,
|
||||
<&cpr_quot00_pwrcl>,
|
||||
<&cpr_quot01_pwrcl>,
|
||||
<&cpr_quot02_pwrcl>,
|
||||
<&cpr_quot_offset01_pwrcl>,
|
||||
<&cpr_quot_offset02_pwrcl>,
|
||||
<&cpr_init_voltage00_pwrcl>,
|
||||
<&cpr_init_voltage01_pwrcl>,
|
||||
<&cpr_init_voltage02_pwrcl>,
|
||||
<&cpr_ro_sel00_pwrcl>,
|
||||
<&cpr_ro_sel01_pwrcl>,
|
||||
<&cpr_ro_sel02_pwrcl>;
|
||||
|
||||
nvmem-cell-names = "cpr_speed_bin",
|
||||
"cpr_fuse_revision",
|
||||
"cpr0_quotient1",
|
||||
"cpr0_quotient2",
|
||||
"cpr0_quotient3",
|
||||
"cpr0_quotient4",
|
||||
"cpr0_quotient5",
|
||||
"cpr0_quotient_offset2",
|
||||
"cpr0_quotient_offset3",
|
||||
"cpr0_quotient_offset4",
|
||||
"cpr0_quotient_offset5",
|
||||
"cpr0_init_voltage1",
|
||||
"cpr0_init_voltage2",
|
||||
"cpr0_init_voltage3",
|
||||
"cpr0_init_voltage4",
|
||||
"cpr0_init_voltage5",
|
||||
"cpr0_ring_osc1",
|
||||
"cpr0_ring_osc2",
|
||||
"cpr0_ring_osc3",
|
||||
"cpr0_ring_osc4",
|
||||
"cpr0_ring_osc5",
|
||||
"cpr1_quotient1",
|
||||
"cpr1_quotient2",
|
||||
"cpr1_quotient3",
|
||||
"cpr1_quotient_offset2",
|
||||
"cpr1_quotient_offset3",
|
||||
"cpr1_init_voltage1",
|
||||
"cpr1_init_voltage2",
|
||||
"cpr1_init_voltage3",
|
||||
"cpr1_ring_osc1",
|
||||
"cpr1_ring_osc2",
|
||||
"cpr1_ring_osc3";
|
||||
};
|
||||
|
||||
tsens: thermal-sensor@10ae000 {
|
||||
compatible = "qcom,sdm630-tsens", "qcom,tsens-v2";
|
||||
reg = <0x010ae000 0x1000>, /* TM */
|
||||
|
|
@ -1048,6 +1573,20 @@
|
|||
|
||||
gpu_sdm630_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-700000000 {
|
||||
opp-hz = /bits/ 64 <700000000>;
|
||||
opp-level = <RPM_SMD_LEVEL_TURBO>;
|
||||
opp-peak-kBps = <5184000>;
|
||||
opp-supported-hw = <0xFF>;
|
||||
};
|
||||
|
||||
/*
|
||||
* 775MHz is only available on default speed bin
|
||||
* or 0xA2 (speed bin 1). Though it cannot be used
|
||||
* for now due to interconnect framework not supporting
|
||||
* multiple frequencies at the same opp-level
|
||||
|
||||
opp-775000000 {
|
||||
opp-hz = /bits/ 64 <775000000>;
|
||||
opp-level = <RPM_SMD_LEVEL_TURBO>;
|
||||
|
|
@ -1090,6 +1629,11 @@
|
|||
opp-peak-kBps = <1200000>;
|
||||
opp-supported-hw = <0xFF>;
|
||||
};
|
||||
*/
|
||||
};
|
||||
|
||||
zap-shader {
|
||||
memory-region = <&zap_shader_region>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -1112,6 +1656,7 @@
|
|||
clock-names = "iface", "mem", "mem_iface";
|
||||
#global-interrupts = <2>;
|
||||
#iommu-cells = <1>;
|
||||
qcom,reset-nodisable-cbs = /bits/ 8 <2 3 4>;
|
||||
|
||||
interrupts =
|
||||
<GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
|
||||
|
|
@ -1125,8 +1670,6 @@
|
|||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpucc: clock-controller@5065000 {
|
||||
|
|
@ -1149,6 +1692,8 @@
|
|||
compatible = "qcom,sdm630-smmu-v2", "qcom,smmu-v2";
|
||||
reg = <0x05100000 0x40000>;
|
||||
#iommu-cells = <1>;
|
||||
qcom,bypass-cbndx = /bits/ 8 <12>;
|
||||
qcom,reset-nodisable-cbs = /bits/ 8 <13>;
|
||||
|
||||
#global-interrupts = <2>;
|
||||
interrupts =
|
||||
|
|
@ -1172,8 +1717,6 @@
|
|||
<GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sram@290000 {
|
||||
|
|
@ -2117,8 +2660,6 @@
|
|||
<GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
adsp_pil: remoteproc@15700000 {
|
||||
|
|
@ -2280,8 +2821,8 @@
|
|||
|
||||
intc: interrupt-controller@17a00000 {
|
||||
compatible = "arm,gic-v3";
|
||||
reg = <0x17a00000 0x10000>, /* GICD */
|
||||
<0x17b00000 0x100000>; /* GICR * 8 */
|
||||
reg = <0x17a00000 0x10000>, /* GICD */
|
||||
<0x17b00000 0x100000>; /* GICR * 8 */
|
||||
#interrupt-cells = <3>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
qcom,pmic-id = <0x1001b 0x101011a 0x00 0x00 0x1001b 0x201011a 0x00 0x00 0x1001b 0x102001a 0x00 0x00>;
|
||||
};
|
||||
|
||||
&panel {
|
||||
compatible = "sony,mermaid-nt36672a-tianma";
|
||||
};
|
||||
|
||||
&sdc2_state_on {
|
||||
pinconf-clk {
|
||||
drive-strength = <14>;
|
||||
|
|
|
|||
717
arch/arm64/boot/dts/qcom/sdm660-xiaomi-platina.dts
Normal file
717
arch/arm64/boot/dts/qcom/sdm660-xiaomi-platina.dts
Normal file
|
|
@ -0,0 +1,717 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "sdm660.dtsi"
|
||||
#include "pm660.dtsi"
|
||||
#include "pm660l.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/input/gpio-keys.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
|
||||
|
||||
/ {
|
||||
model = "Xiaomi Mi 8 Lite";
|
||||
compatible = "xiaomi,platina", "qcom,sdm660";
|
||||
|
||||
aliases {
|
||||
serial0 = &blsp1_uart2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
ramoops@ffc00000 {
|
||||
compatible = "ramoops";
|
||||
reg = <0x0 0xffc00000 0x0 0x100000>;
|
||||
record-size = <0x10000>;
|
||||
console-size = <0x60000>;
|
||||
ftrace-size = <0x10000>;
|
||||
pmsg-size = <0x20000>;
|
||||
ecc-size = <16>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
debug_region@ffb00000 {
|
||||
reg = <0x00 0xffb00000 0x00 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
cdsp-region@94e00000 {
|
||||
reg = <0x00 0x94e00000 0x00 0x600000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
removed_region@85800000 {
|
||||
reg = <0x00 0x85800000 0x00 0x3700000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
board_vbat: vbat-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "VBAT";
|
||||
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <4000000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
cam_avdd_front_vreg: cam-avdd-front-vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "cam-avdd-front-vreg";
|
||||
|
||||
regulator-min-microvolt = <3600000>;
|
||||
regulator-max-microvolt = <3600000>;
|
||||
startup-delay-us = <0>;
|
||||
enable-active-high;
|
||||
gpio = <&tlmm 49 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cam_avdd_front_default>;
|
||||
vin-supply = <&vreg_bob>;
|
||||
};
|
||||
|
||||
cam_actuator_rear_vreg: cam-actuator-rear-vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "cam-actuator-rear-vreg";
|
||||
|
||||
regulator-min-microvolt = <3600000>;
|
||||
regulator-max-microvolt = <3600000>;
|
||||
startup-delay-us = <0>;
|
||||
enable-active-high;
|
||||
gpio = <&tlmm 50 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cam_actuator_rear_default>;
|
||||
vin-supply = <&vreg_bob>;
|
||||
};
|
||||
|
||||
cam_avdd_rear_vreg: cam-avdd-rear-vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "cam-avdd-rear-vreg";
|
||||
|
||||
regulator-min-microvolt = <3600000>;
|
||||
regulator-max-microvolt = <3600000>;
|
||||
startup-delay-us = <0>;
|
||||
enable-active-high;
|
||||
gpio = <&tlmm 51 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cam_avdd_rear_default>;
|
||||
vin-supply = <&vreg_bob>;
|
||||
};
|
||||
|
||||
cam_dvdd_front_vreg: cam-dvdd-front-vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "cam-dvdd-front-vreg";
|
||||
|
||||
regulator-min-microvolt = <1350000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
startup-delay-us = <0>;
|
||||
enable-active-high;
|
||||
gpio = <&pm660l_gpios 3 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cam_dvdd_front_default>;
|
||||
vin-supply = <&vreg_s5a_1p35>;
|
||||
};
|
||||
|
||||
cam_dvdd_rear_vreg: cam-dvdd-rear-vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "cam-dvdd-rear-vreg";
|
||||
|
||||
regulator-min-microvolt = <1350000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
startup-delay-us = <0>;
|
||||
enable-active-high;
|
||||
gpio = <&pm660l_gpios 4 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cam_dvdd_rear_default>;
|
||||
vin-supply = <&vreg_s5a_1p35>;
|
||||
};
|
||||
|
||||
disp_vdd_vreg: disp-vdd-vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "display-vdd";
|
||||
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
ts_vdd_vreg: ts-vdd-vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "ts-vdd";
|
||||
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
startup-delay-us = <4000>;
|
||||
enable-active-high;
|
||||
regulator-boot-on;
|
||||
gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ts_vdd_default>;
|
||||
};
|
||||
|
||||
vph_pwr: vph-pwr-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vph_pwr";
|
||||
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
gpio_keys {
|
||||
status = "okay";
|
||||
compatible = "gpio-keys";
|
||||
input-name = "gpio-keys";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
vol_up {
|
||||
label = "Volume Up";
|
||||
gpios = <&pm660l_gpios 7 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <1>;
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
wakeup-source;
|
||||
debounce-interval = <15>;
|
||||
};
|
||||
};
|
||||
|
||||
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 75 GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <EV_SW>;
|
||||
linux,code = <SW_LID>;
|
||||
linux,can-disable;
|
||||
wakeup-source;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Until we hook up type-c detection, we
|
||||
* have to stick with this. But it works.
|
||||
*/
|
||||
extcon_usb: extcon-usb {
|
||||
compatible = "linux,extcon-usb-gpio";
|
||||
id-gpio = <&tlmm 58 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp_i2c2 {
|
||||
status = "okay";
|
||||
|
||||
/*
|
||||
* Two instances of SMB1355 charger: 0x8, 0xc but only
|
||||
* one SMB1355 chip is present on board. What's the
|
||||
* right address?
|
||||
*/
|
||||
};
|
||||
|
||||
&blsp1_uart2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&rpm_requests {
|
||||
pm660l-regulators {
|
||||
compatible = "qcom,rpm-pm660l-regulators";
|
||||
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
vdd_s2-supply = <&vph_pwr>;
|
||||
vdd_s3_s4-supply = <&vph_pwr>;
|
||||
vdd_s5-supply = <&vph_pwr>;
|
||||
vdd_s6-supply = <&vph_pwr>;
|
||||
|
||||
vdd_l1_l9_l10-supply = <&vreg_s2b_1p05>;
|
||||
vdd_l2-supply = <&vreg_bob>;
|
||||
vdd_l3_l5_l7_l8-supply = <&vreg_bob>;
|
||||
vdd_l4_l6-supply = <&vreg_bob>;
|
||||
vdd_bob-supply = <&vph_pwr>;
|
||||
|
||||
vreg_s1b_1p125: s1 {
|
||||
regulator-min-microvolt = <1125000>;
|
||||
regulator-max-microvolt = <1125000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_s2b_1p05: s2 {
|
||||
regulator-min-microvolt = <1050000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/*
|
||||
* At least on Nile's configuration, S3B/S4B (VDD_CX) and
|
||||
* S5B (VDD_MX) are managed only through RPM Power Domains.
|
||||
* Trying to set a voltage on the main supply will create
|
||||
* havoc and freeze the SoC.
|
||||
* In any case, reference voltages for these regulators are:
|
||||
* S3B/S4B: 0.870V
|
||||
* S5B: 0.915V
|
||||
*/
|
||||
|
||||
/* LDOs */
|
||||
vreg_l1b_0p925: l1 {
|
||||
regulator-min-microvolt = <920000>;
|
||||
regulator-max-microvolt = <928000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l2b_2p95: l2 {
|
||||
/*
|
||||
* This regulator supports 1.648 - 3.104V on this board
|
||||
* but we set a max voltage of anything less than 2.7V
|
||||
* to satisfy a condition in sdhci.c that will disable
|
||||
* 3.3V SDHCI signaling, which happens to be not really
|
||||
* supported on the Xperia Nile/Ganges platform.
|
||||
*/
|
||||
regulator-min-microvolt = <1648000>;
|
||||
regulator-max-microvolt = <2696000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l3b_3p3: l3 {
|
||||
regulator-min-microvolt = <3296000>;
|
||||
regulator-max-microvolt = <3312000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-min-microamp = <200>;
|
||||
regulator-max-microamp = <600000>;
|
||||
regulator-system-load = <100000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l4b_2p95: l4 {
|
||||
regulator-min-microvolt = <2944000>;
|
||||
regulator-max-microvolt = <2952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
|
||||
regulator-min-microamp = <200>;
|
||||
regulator-max-microamp = <600000>;
|
||||
regulator-system-load = <570000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
/*
|
||||
* Downstream specifies a range of 1721-3600mV,
|
||||
* but the only assigned consumers are SDHCI2 VMMC
|
||||
* and Coresight QPDI that both request pinned 2.95V.
|
||||
* Tighten the range to 1.8-3.328 (closest to 3.3) to
|
||||
* make the mmc driver happy.
|
||||
*/
|
||||
vreg_l5b_29p5: l5 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3328000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
regulator-system-load = <800000>;
|
||||
};
|
||||
|
||||
vreg_l7b_3p125: l7 {
|
||||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <3128000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l8b_3p3: l8 {
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/* L9B (870mV) is currently unused */
|
||||
/* L10B (915mV) is currently unused */
|
||||
|
||||
vreg_bob: bob {
|
||||
regulator-min-microvolt = <3304000>;
|
||||
regulator-max-microvolt = <3624000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
pm660-regulators {
|
||||
compatible = "qcom,rpm-pm660-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_l1_l6_l7-supply = <&vreg_s5a_1p35>;
|
||||
vdd_l2_l3-supply = <&vreg_s2b_1p05>;
|
||||
vdd_l5-supply = <&vreg_s2b_1p05>;
|
||||
vdd_l8_l9_l10_l11_l12_l13_l14-supply = <&vreg_s4a_2p04>;
|
||||
vdd_l15_l16_l17_l18_l19-supply = <&vreg_bob>;
|
||||
|
||||
/*
|
||||
* S1A (FTAPC0), S2A (FTAPC1), S3A (HFAPC1) are managed
|
||||
* by the Core Power Reduction hardened (CPRh) and the
|
||||
* Operating State Manager (OSM) HW automatically.
|
||||
*/
|
||||
|
||||
vreg_s4a_2p04: s4 {
|
||||
regulator-min-microvolt = <2040000>;
|
||||
regulator-max-microvolt = <2040000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vreg_s5a_1p35: s5 {
|
||||
regulator-min-microvolt = <1224000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-enable-ramp-delay = <200>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_s6a_0p87: s6 {
|
||||
regulator-min-microvolt = <504000>;
|
||||
regulator-max-microvolt = <992000>;
|
||||
regulator-enable-ramp-delay = <150>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/* LDOs */
|
||||
vreg_l1a_1p225: l1 {
|
||||
regulator-min-microvolt = <1226000>;
|
||||
regulator-max-microvolt = <1250000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l2a_1p0: l2 {
|
||||
regulator-min-microvolt = <944000>;
|
||||
regulator-max-microvolt = <1008000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l3a_1p0: l3 {
|
||||
regulator-min-microvolt = <944000>;
|
||||
regulator-max-microvolt = <1008000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l5a_0p848: l5 {
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l6a_1p3: l6 {
|
||||
regulator-min-microvolt = <1304000>;
|
||||
regulator-max-microvolt = <1368000>;
|
||||
regulator-allow-set-load;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l7a_1p2: l7 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l8a_1p8: l8 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-system-load = <325000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
|
||||
vreg_l9a_1p8: l9 {
|
||||
regulator-min-microvolt = <1804000>;
|
||||
regulator-max-microvolt = <1896000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l10a_1p8: l10 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1944000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l11a_1p8: l11 {
|
||||
regulator-min-microvolt = <1784000>;
|
||||
regulator-max-microvolt = <1944000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l12a_1p8: l12 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1944000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l13a_1p8: l13 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1944000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vreg_l14a_1p8: l14 {
|
||||
regulator-min-microvolt = <1710000>;
|
||||
regulator-max-microvolt = <1952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l15a_1p8: l15 {
|
||||
regulator-min-microvolt = <1648000>;
|
||||
regulator-max-microvolt = <2952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/* DRX: QM13111 */
|
||||
vreg_l16a_2p7: l16 {
|
||||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <2712000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
vreg_l17a_1p8: l17 {
|
||||
regulator-min-microvolt = <1648000>;
|
||||
regulator-max-microvolt = <2952000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
};
|
||||
|
||||
/* L18A (2.7V) is unused */
|
||||
|
||||
vreg_l19a_3p3: l19 {
|
||||
regulator-min-microvolt = <3312000>;
|
||||
regulator-max-microvolt = <3328000>;
|
||||
regulator-enable-ramp-delay = <250>;
|
||||
regulator-ramp-delay = <0>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&sdhc_1 {
|
||||
status = "okay";
|
||||
supports-cqe;
|
||||
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs400-1_8v;
|
||||
mmc-hs400-enhanced-strobe;
|
||||
|
||||
vmmc-supply = <&vreg_l4b_2p95>;
|
||||
vqmmc-supply = <&vreg_l8a_1p8>;
|
||||
};
|
||||
|
||||
&sdhc_2 {
|
||||
status = "disabled";
|
||||
|
||||
vmmc-supply = <&vreg_l5b_29p5>;
|
||||
vqmmc-supply = <&vreg_l2b_2p95>;
|
||||
};
|
||||
|
||||
&pm660_gpios {
|
||||
nfc_clk_req_n: nfc-clkreq-n {
|
||||
pins = "gpio4";
|
||||
function = PMIC_GPIO_FUNC_NORMAL;
|
||||
bias-disable;
|
||||
input-enable;
|
||||
power-source = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
&pm660l_gpios {
|
||||
cam_dvdd_front_default: cam-dvdd-front-default {
|
||||
pins = "gpio3";
|
||||
function = "normal";
|
||||
output-low;
|
||||
power-source = <0>;
|
||||
};
|
||||
|
||||
cam_dvdd_rear_default: cam-dvdd-rear-default {
|
||||
pins = "gpio4";
|
||||
function = "normal";
|
||||
output-low;
|
||||
power-source = <0>;
|
||||
};
|
||||
|
||||
vol_key_gpio_default: vol-key-gpio-default {
|
||||
pins = "gpio7";
|
||||
function = "normal";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
gpio-reserved-ranges = <8 4>;
|
||||
|
||||
camera_rear_default: camera-rear-default {
|
||||
mclk0 {
|
||||
pins = "gpio32";
|
||||
function = "cam_mclk";
|
||||
drive-strength = <4>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
rst {
|
||||
pins = "gpio46";
|
||||
function = "gpio";
|
||||
drive-strength = <16>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
camera_front_default: camera-front-default {
|
||||
mclk1 {
|
||||
pins = "gpio33";
|
||||
function = "cam_mclk";
|
||||
drive-strength = <4>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
rst {
|
||||
pins = "gpio47";
|
||||
function = "gpio";
|
||||
drive-strength = <16>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
camera_front_iris_default: camera-front-iris-default {
|
||||
mclk1 {
|
||||
pins = "gpio35";
|
||||
function = "cam_mclk";
|
||||
drive-strength = <4>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
rst {
|
||||
pins = "gpio52";
|
||||
function = "gpio";
|
||||
drive-strength = <16>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
cam_avdd_front_default: cam-avdd-front-default {
|
||||
pins = "gpio49";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
cam_actuator_rear_default: cam-actuator-rear-default {
|
||||
pins = "gpio50";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
cam_avdd_rear_default: cam-avdd-rear-default {
|
||||
pins = "gpio51";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
panel_reset_n: panel-rst-n {
|
||||
pins = "gpio53";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
mdp_vsync_n: mdp-vsync-n {
|
||||
pins = "gpio59";
|
||||
function = "mdp_vsync";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
ts_rst_n: ts-rst-n {
|
||||
pins = "gpio66";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
ts_int_active: ts-int-active {
|
||||
pins = "gpio67";
|
||||
drive-strength = <16>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
ts_vdd_default: ts-vdd-default {
|
||||
pins = "gpio73";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
hall_sensor_default: hall-sensor-default {
|
||||
pins = "gpio75";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
input-enable;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&usb3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3_dwc3 {
|
||||
dr_mode = "peripheral";
|
||||
extcon = <&extcon_usb>;
|
||||
};
|
||||
|
|
@ -595,6 +595,30 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pmi8998_lpg {
|
||||
status = "okay";
|
||||
|
||||
qcom,power-source = <1>;
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
label = "green:user3";
|
||||
|
||||
linux,default-trigger = "heartbeat";
|
||||
default-state = "on";
|
||||
};
|
||||
|
||||
led@4 {
|
||||
reg = <4>;
|
||||
label = "green:user2";
|
||||
};
|
||||
|
||||
led@5 {
|
||||
reg = <5>;
|
||||
label = "green:user1";
|
||||
};
|
||||
};
|
||||
|
||||
/* QUAT I2S Uses 4 I2S SD Lines for audio on LT9611 HDMI Bridge */
|
||||
&q6afedai {
|
||||
qi2s@22 {
|
||||
|
|
|
|||
|
|
@ -450,6 +450,19 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pmi8998_fg {
|
||||
status = "okay";
|
||||
|
||||
qcom,max-voltage-uv = <4400000>;
|
||||
qcom,min-voltage-uv = <3700000>;
|
||||
};
|
||||
|
||||
&pmi8998_haptics {
|
||||
status = "okay";
|
||||
|
||||
qcom,wave-play-rate-us = <4255>;
|
||||
};
|
||||
|
||||
&qupv3_id_1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
@ -619,7 +632,7 @@
|
|||
pins = "gpio6", "gpio25", "gpio26";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable = <0>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@
|
|||
chassis-type = "handset";
|
||||
};
|
||||
|
||||
&pmi8998_fg {
|
||||
qcom,battery-capacity-ua = <3300000>;
|
||||
};
|
||||
|
||||
&display_panel {
|
||||
status = "okay";
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
compatible = "samsung,s6e3fc2x01";
|
||||
};
|
||||
|
||||
&pmi8998_fg {
|
||||
qcom,battery-capacity-ua = <3700000>;
|
||||
};
|
||||
|
||||
&rmi4_f12 {
|
||||
touchscreen-y-mm = <148>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -334,6 +334,11 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pmi8998_haptics {
|
||||
status = "okay";
|
||||
qcom,wave-play-rate-us = <4878>;
|
||||
};
|
||||
|
||||
&qupv3_id_0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
|||
631
arch/arm64/configs/sdm660_defconfig
Normal file
631
arch/arm64/configs/sdm660_defconfig
Normal file
|
|
@ -0,0 +1,631 @@
|
|||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_CGROUP_PIDS=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_HUGETLB=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
CONFIG_CGROUP_BPF=y
|
||||
CONFIG_CGROUP_DEBUG=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BOOT_CONFIG=y
|
||||
# CONFIG_FHANDLE is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_ARCH_QCOM=y
|
||||
CONFIG_ARM64_VA_BITS_48=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_NR_CPUS=4
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_ARM64_SW_TTBR0_PAN=y
|
||||
CONFIG_COMPAT=y
|
||||
CONFIG_ARMV8_DEPRECATED=y
|
||||
CONFIG_SWP_EMULATION=y
|
||||
CONFIG_CP15_BARRIER_EMULATION=y
|
||||
CONFIG_SETEND_EMULATION=y
|
||||
CONFIG_RANDOMIZE_BASE=y
|
||||
# CONFIG_EFI is not set
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_PM_AUTOSLEEP=y
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=0
|
||||
# CONFIG_PM_WAKELOCKS_GC is not set
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
|
||||
CONFIG_ENERGY_MODEL=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_ARM_CPUIDLE=y
|
||||
CONFIG_ARM_PSCI_CPUIDLE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPUFREQ_DT=y
|
||||
CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
|
||||
CONFIG_ARM_QCOM_CPUFREQ_HW=y
|
||||
CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT=y
|
||||
CONFIG_ARM64_CRYPTO=y
|
||||
CONFIG_CRYPTO_SHA1_ARM64_CE=y
|
||||
CONFIG_CRYPTO_SHA2_ARM64_CE=y
|
||||
CONFIG_CRYPTO_SHA512_ARM64_CE=y
|
||||
CONFIG_CRYPTO_SHA3_ARM64=y
|
||||
CONFIG_CRYPTO_SM3_ARM64_CE=y
|
||||
CONFIG_CRYPTO_SM4_ARM64_CE=y
|
||||
CONFIG_CRYPTO_GHASH_ARM64_CE=y
|
||||
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
|
||||
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
|
||||
CONFIG_CRYPTO_POLY1305_NEON=y
|
||||
CONFIG_CRYPTO_NHPOLY1305_NEON=y
|
||||
CONFIG_CRYPTO_AES_ARM64_BS=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_KSM=y
|
||||
CONFIG_MEMORY_FAILURE=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_FRONTSWAP=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_ZSMALLOC=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_DIAG_DESTROY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_ESP=y
|
||||
CONFIG_INET6_IPCOMP=y
|
||||
CONFIG_IPV6_MIP6=y
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=y
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=y
|
||||
CONFIG_NF_CONNTRACK_FTP=y
|
||||
CONFIG_NF_CONNTRACK_H323=y
|
||||
CONFIG_NF_CONNTRACK_IRC=y
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
|
||||
CONFIG_NF_CONNTRACK_PPTP=y
|
||||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=y
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=y
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_MATCH_AH=y
|
||||
CONFIG_IP_NF_MATCH_ECN=y
|
||||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_IP_NF_NAT=y
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=y
|
||||
CONFIG_IP_NF_TARGET_NETMAP=y
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=y
|
||||
CONFIG_IP_NF_MANGLE=y
|
||||
CONFIG_IP_NF_RAW=y
|
||||
CONFIG_IP_NF_SECURITY=y
|
||||
CONFIG_IP_NF_ARPTABLES=y
|
||||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT=y
|
||||
CONFIG_IP6_NF_MANGLE=y
|
||||
CONFIG_IP6_NF_RAW=y
|
||||
CONFIG_IP6_NF_NAT=y
|
||||
CONFIG_IP6_NF_TARGET_MASQUERADE=y
|
||||
CONFIG_BRIDGE=y
|
||||
CONFIG_BRIDGE_VLAN_FILTERING=y
|
||||
CONFIG_VLAN_8021Q=y
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_VLAN_8021Q_MVRP=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_CLS_U32=y
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_U32=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_QRTR=y
|
||||
CONFIG_QRTR_SMD=y
|
||||
CONFIG_QRTR_TUN=y
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_HIDP=y
|
||||
CONFIG_BT_LEDS=y
|
||||
CONFIG_BT_HCIBTUSB=y
|
||||
CONFIG_BT_HCIUART=y
|
||||
CONFIG_BT_HCIUART_QCA=y
|
||||
CONFIG_BT_QCOMSMD=y
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_MAC80211=y
|
||||
CONFIG_MAC80211_LEDS=y
|
||||
CONFIG_RFKILL=y
|
||||
CONFIG_NFC=y
|
||||
CONFIG_NFC_NCI=y
|
||||
CONFIG_NFC_NXP_NCI=y
|
||||
CONFIG_NFC_NXP_NCI_I2C=y
|
||||
CONFIG_NFC_S3FWRN5_I2C=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIE_QCOM=y
|
||||
CONFIG_UEVENT_HELPER=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_EXTRA_FIRMWARE="qcom/a508_zap.b00 qcom/a508_zap.b01 qcom/a508_zap.b02 qcom/a508_zap.elf qcom/a508_zap.mdt qcom/a530_gpmu.fw2 qcom/a530_pfp.fw qcom/a530_pm4.fw"
|
||||
CONFIG_EXTRA_FIRMWARE_DIR="../firmware/"
|
||||
CONFIG_FW_LOADER_USER_HELPER=y
|
||||
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
|
||||
CONFIG_FW_LOADER_COMPRESS=y
|
||||
# CONFIG_QCOM_EBI2 is not set
|
||||
CONFIG_OF_OVERLAY=y
|
||||
CONFIG_ZRAM=y
|
||||
CONFIG_ZRAM_WRITEBACK=y
|
||||
CONFIG_ZRAM_MEMORY_TRACKING=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
CONFIG_QCOM_COINCELL=y
|
||||
CONFIG_QCOM_FASTRPC=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_MACVLAN=y
|
||||
CONFIG_MACVTAP=y
|
||||
CONFIG_VXLAN=y
|
||||
CONFIG_TUN=y
|
||||
CONFIG_VETH=y
|
||||
CONFIG_QCOM_IPA=y
|
||||
CONFIG_PPP=y
|
||||
CONFIG_PPP_BSDCOMP=y
|
||||
CONFIG_PPP_DEFLATE=y
|
||||
CONFIG_PPP_FILTER=y
|
||||
CONFIG_PPP_MPPE=y
|
||||
CONFIG_PPP_ASYNC=y
|
||||
CONFIG_USB_USBNET=y
|
||||
CONFIG_ATH10K=y
|
||||
CONFIG_ATH10K_SNOC=y
|
||||
CONFIG_WCN36XX=y
|
||||
CONFIG_INPUT_MATRIXKMAP=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
CONFIG_KEYBOARD_GPIO=y
|
||||
CONFIG_KEYBOARD_TM2_TOUCHKEY=y
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
CONFIG_JOYSTICK_XPAD=y
|
||||
CONFIG_JOYSTICK_XPAD_FF=y
|
||||
CONFIG_JOYSTICK_XPAD_LEDS=y
|
||||
CONFIG_INPUT_TABLET=y
|
||||
CONFIG_TABLET_USB_ACECAD=y
|
||||
CONFIG_TABLET_USB_AIPTEK=y
|
||||
CONFIG_TABLET_USB_HANWANG=y
|
||||
CONFIG_TABLET_USB_KBTAB=y
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
|
||||
CONFIG_TOUCHSCREEN_MMS114=y
|
||||
CONFIG_TOUCHSCREEN_EDT_FT5X06=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_PM8941_PWRKEY=y
|
||||
CONFIG_INPUT_PM8XXX_VIBRATOR=y
|
||||
CONFIG_INPUT_GPIO_VIBRA=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
CONFIG_RMI4_CORE=y
|
||||
CONFIG_RMI4_I2C=y
|
||||
CONFIG_RMI4_F11=y
|
||||
CONFIG_RMI4_F12=y
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_SERIAL_MSM=y
|
||||
CONFIG_SERIAL_MSM_CONSOLE=y
|
||||
CONFIG_SERIAL_DEV_BUS=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
# CONFIG_DEVMEM is not set
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_GPIO=y
|
||||
CONFIG_I2C_QCOM_CCI=y
|
||||
CONFIG_I2C_QUP=y
|
||||
CONFIG_I2C_SLAVE=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_MEM=y
|
||||
CONFIG_SPI_BITBANG=y
|
||||
CONFIG_SPI_QUP=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_PTP_1588_CLOCK=y
|
||||
CONFIG_PINCTRL_SINGLE=y
|
||||
CONFIG_PINCTRL_MSM=y
|
||||
CONFIG_PINCTRL_MSM8976=y
|
||||
CONFIG_PINCTRL_MSM8996=y
|
||||
CONFIG_PINCTRL_MSM8998=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_PINCTRL_SDM660=y
|
||||
CONFIG_GPIO_WCD934X=y
|
||||
CONFIG_POWER_RESET_MSM=y
|
||||
CONFIG_POWER_RESET_QCOM_PON=y
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_DEVFREQ_THERMAL=y
|
||||
CONFIG_THERMAL_EMULATION=y
|
||||
CONFIG_QCOM_TSENS=y
|
||||
CONFIG_QCOM_SPMI_TEMP_ALARM=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_MFD_QCOM_RPM=y
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_MFD_RT5033=y
|
||||
CONFIG_MFD_WCD934X=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
|
||||
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
|
||||
CONFIG_REGULATOR_GPIO=y
|
||||
CONFIG_REGULATOR_QCOM_SMD_RPM=y
|
||||
CONFIG_REGULATOR_QCOM_SPMI=y
|
||||
CONFIG_REGULATOR_VCTRL=y
|
||||
CONFIG_REGULATOR_QCOM_LABIBB=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_VIDEO_QCOM_CAMSS=y
|
||||
CONFIG_V4L_MEM2MEM_DRIVERS=y
|
||||
CONFIG_VIDEO_MEM2MEM_DEINTERLACE=y
|
||||
CONFIG_VIDEO_QCOM_VENUS=y
|
||||
CONFIG_VIDEO_IMX219=y
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_MSM=y
|
||||
# CONFIG_DRM_MSM_DSI_20NM_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_28NM_8960_PHY is not set
|
||||
# CONFIG_DRM_MSM_DSI_7NM_PHY is not set
|
||||
CONFIG_DRM_PANEL_SIMPLE=y
|
||||
CONFIG_DRM_PANEL_SONY_DISCOVERY_TD4322_INNOLUX=y
|
||||
CONFIG_DRM_LEGACY=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_LCD_CLASS_DEVICE=y
|
||||
CONFIG_LCD_PLATFORM=y
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_BACKLIGHT_PWM=y
|
||||
CONFIG_BACKLIGHT_QCOM_WLED=y
|
||||
CONFIG_BACKLIGHT_GPIO=y
|
||||
CONFIG_BACKLIGHT_LED=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_DYNAMIC_MINORS=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_SOC_QCOM=y
|
||||
CONFIG_SND_SOC_APQ8016_SBC=y
|
||||
CONFIG_SND_SOC_MSM8996=y
|
||||
CONFIG_SND_SOC_MSM8916_WCD_ANALOG=y
|
||||
CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=y
|
||||
CONFIG_SND_SOC_WCD9335=y
|
||||
CONFIG_HIDRAW=y
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_A4TECH=y
|
||||
CONFIG_HID_ACRUX=y
|
||||
CONFIG_HID_ACRUX_FF=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_BELKIN=y
|
||||
CONFIG_HID_CHERRY=y
|
||||
CONFIG_HID_CHICONY=y
|
||||
CONFIG_HID_PRODIKEYS=y
|
||||
CONFIG_HID_CYPRESS=y
|
||||
CONFIG_HID_DRAGONRISE=y
|
||||
CONFIG_DRAGONRISE_FF=y
|
||||
CONFIG_HID_EMS_FF=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
CONFIG_HID_EZKEY=y
|
||||
CONFIG_HID_HOLTEK=y
|
||||
CONFIG_HID_KEYTOUCH=y
|
||||
CONFIG_HID_KYE=y
|
||||
CONFIG_HID_UCLOGIC=y
|
||||
CONFIG_HID_WALTOP=y
|
||||
CONFIG_HID_GYRATION=y
|
||||
CONFIG_HID_TWINHAN=y
|
||||
CONFIG_HID_KENSINGTON=y
|
||||
CONFIG_HID_LCPOWER=y
|
||||
CONFIG_HID_LOGITECH=y
|
||||
CONFIG_HID_LOGITECH_DJ=y
|
||||
CONFIG_LOGITECH_FF=y
|
||||
CONFIG_LOGIRUMBLEPAD2_FF=y
|
||||
CONFIG_LOGIG940_FF=y
|
||||
CONFIG_HID_MAGICMOUSE=y
|
||||
CONFIG_HID_MICROSOFT=y
|
||||
CONFIG_HID_MONTEREY=y
|
||||
CONFIG_HID_MULTITOUCH=y
|
||||
CONFIG_HID_NTRIG=y
|
||||
CONFIG_HID_ORTEK=y
|
||||
CONFIG_HID_PANTHERLORD=y
|
||||
CONFIG_PANTHERLORD_FF=y
|
||||
CONFIG_HID_PETALYNX=y
|
||||
CONFIG_HID_PICOLCD=y
|
||||
CONFIG_HID_PRIMAX=y
|
||||
CONFIG_HID_ROCCAT=y
|
||||
CONFIG_HID_SAITEK=y
|
||||
CONFIG_HID_SAMSUNG=y
|
||||
CONFIG_HID_SONY=y
|
||||
CONFIG_HID_SPEEDLINK=y
|
||||
CONFIG_HID_SUNPLUS=y
|
||||
CONFIG_HID_GREENASIA=y
|
||||
CONFIG_GREENASIA_FF=y
|
||||
CONFIG_HID_SMARTJOYPLUS=y
|
||||
CONFIG_SMARTJOYPLUS_FF=y
|
||||
CONFIG_HID_TIVO=y
|
||||
CONFIG_HID_TOPSEED=y
|
||||
CONFIG_HID_THRUSTMASTER=y
|
||||
CONFIG_HID_WACOM=y
|
||||
CONFIG_HID_WIIMOTE=y
|
||||
CONFIG_HID_ZEROPLUS=y
|
||||
CONFIG_HID_ZYDACRON=y
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_USB_LED_TRIG=y
|
||||
CONFIG_USB_CONN_GPIO=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_OTG=y
|
||||
CONFIG_USB_OTG_FSM=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_DWC3=y
|
||||
CONFIG_USB_DWC3_ULPI=y
|
||||
CONFIG_USB_CHIPIDEA=y
|
||||
CONFIG_USB_CHIPIDEA_UDC=y
|
||||
CONFIG_USB_CHIPIDEA_HOST=y
|
||||
CONFIG_USB_GPIO_VBUS=y
|
||||
CONFIG_USB_ULPI=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_VBUS_DRAW=500
|
||||
CONFIG_U_SERIAL_CONSOLE=y
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
CONFIG_USB_CONFIGFS_SERIAL=y
|
||||
CONFIG_USB_CONFIGFS_RNDIS=y
|
||||
CONFIG_USB_CONFIGFS_EEM=y
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
CONFIG_USB_CONFIGFS_F_MIDI=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK_MINORS=64
|
||||
CONFIG_MMC_DEBUG=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_MSM=y
|
||||
CONFIG_LEDS_CLASS_MULTICOLOR=y
|
||||
CONFIG_LEDS_QCOM_LPG=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_ONESHOT=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_LEDS_TRIGGER_CPU=y
|
||||
CONFIG_LEDS_TRIGGER_ACTIVITY=y
|
||||
CONFIG_LEDS_TRIGGER_GPIO=y
|
||||
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
|
||||
CONFIG_LEDS_TRIGGER_TRANSIENT=y
|
||||
CONFIG_LEDS_TRIGGER_CAMERA=y
|
||||
CONFIG_LEDS_TRIGGER_PANIC=y
|
||||
CONFIG_LEDS_TRIGGER_NETDEV=y
|
||||
CONFIG_LEDS_TRIGGER_PATTERN=y
|
||||
CONFIG_LEDS_TRIGGER_AUDIO=y
|
||||
CONFIG_LEDS_TRIGGER_TTY=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_PM8XXX=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_QCOM_BAM_DMA=y
|
||||
CONFIG_QCOM_HIDMA_MGMT=y
|
||||
CONFIG_QCOM_HIDMA=y
|
||||
# CONFIG_VIRTIO_MENU is not set
|
||||
# CONFIG_VHOST_MENU is not set
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_ASHMEM=y
|
||||
CONFIG_COMMON_CLK_QCOM=y
|
||||
CONFIG_QCOM_CLK_APCC_MSM8996=y
|
||||
CONFIG_QCOM_CLK_RPM=y
|
||||
CONFIG_QCOM_CLK_SMD_RPM=y
|
||||
CONFIG_MSM_MMCC_8996=y
|
||||
CONFIG_MSM_GPUCC_8998=y
|
||||
CONFIG_MSM_MMCC_8998=y
|
||||
CONFIG_SDM_MMCC_660=y
|
||||
CONFIG_SDM_GPUCC_660=y
|
||||
CONFIG_SPMI_PMIC_CLKDIV=y
|
||||
CONFIG_QCOM_HFPLL=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_QCOM=y
|
||||
CONFIG_MAILBOX=y
|
||||
CONFIG_QCOM_APCS_IPC=y
|
||||
CONFIG_QCOM_IPCC=y
|
||||
CONFIG_ARM_SMMU=y
|
||||
CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS=y
|
||||
CONFIG_QCOM_IOMMU=y
|
||||
CONFIG_REMOTEPROC=y
|
||||
CONFIG_REMOTEPROC_CDEV=y
|
||||
CONFIG_QCOM_Q6V5_ADSP=y
|
||||
CONFIG_QCOM_Q6V5_MSS=y
|
||||
CONFIG_QCOM_Q6V5_PAS=y
|
||||
CONFIG_QCOM_Q6V5_WCSS=y
|
||||
CONFIG_QCOM_SYSMON=y
|
||||
CONFIG_QCOM_WCNSS_PIL=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_RPM=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
|
||||
CONFIG_RPMSG_QCOM_SMD=y
|
||||
CONFIG_SOUNDWIRE=y
|
||||
CONFIG_SOUNDWIRE_QCOM=y
|
||||
CONFIG_QCOM_AOSS_QMP=y
|
||||
CONFIG_QCOM_CPR=y
|
||||
CONFIG_QCOM_GSBI=y
|
||||
CONFIG_QCOM_LLCC=y
|
||||
CONFIG_QCOM_OCMEM=y
|
||||
CONFIG_QCOM_RMTFS_MEM=y
|
||||
CONFIG_QCOM_RPMPD=y
|
||||
CONFIG_QCOM_SMEM=y
|
||||
CONFIG_QCOM_SMD_RPM=y
|
||||
CONFIG_QCOM_SMP2P=y
|
||||
CONFIG_QCOM_SMSM=y
|
||||
CONFIG_QCOM_SOCINFO=y
|
||||
CONFIG_QCOM_WCNSS_CTRL=y
|
||||
CONFIG_QCOM_APR=y
|
||||
CONFIG_PM_DEVFREQ=y
|
||||
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
|
||||
CONFIG_EXTCON_ADC_JACK=y
|
||||
CONFIG_EXTCON_GPIO=y
|
||||
CONFIG_EXTCON_QCOM_SPMI_MISC=y
|
||||
CONFIG_EXTCON_SM5502=y
|
||||
CONFIG_EXTCON_USB_GPIO=y
|
||||
CONFIG_MEMORY=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_BMA180=y
|
||||
CONFIG_BMC150_ACCEL=y
|
||||
CONFIG_QCOM_SPMI_IADC=y
|
||||
CONFIG_QCOM_SPMI_VADC=y
|
||||
CONFIG_QCOM_SPMI_ADC5=y
|
||||
CONFIG_BMG160=y
|
||||
CONFIG_INV_MPU6050_SPI=y
|
||||
CONFIG_IIO_ST_LSM6DSX=y
|
||||
CONFIG_LTR501=y
|
||||
CONFIG_AK09911=y
|
||||
CONFIG_BMC150_MAGN_I2C=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_QCOM_PDC=y
|
||||
CONFIG_PHY_QCOM_PCIE2=y
|
||||
CONFIG_PHY_QCOM_QMP=y
|
||||
CONFIG_PHY_QCOM_QUSB2=y
|
||||
CONFIG_PHY_QCOM_USB_HS=y
|
||||
CONFIG_PHY_QCOM_USB_HSIC=y
|
||||
CONFIG_PHY_QCOM_USB_HS_28NM=y
|
||||
CONFIG_POWERCAP=y
|
||||
CONFIG_IDLE_INJECT=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_QCOM_QFPROM=y
|
||||
CONFIG_NVMEM_SPMI_SDAM=y
|
||||
CONFIG_SLIM_QCOM_CTRL=y
|
||||
CONFIG_SLIM_QCOM_NGD_CTRL=y
|
||||
CONFIG_INTERCONNECT=y
|
||||
CONFIG_INTERCONNECT_QCOM=y
|
||||
CONFIG_INTERCONNECT_QCOM_SDM660=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_F2FS_FS=y
|
||||
CONFIG_F2FS_FS_COMPRESSION=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QFMT_V1=y
|
||||
CONFIG_QFMT_V2=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
CONFIG_OVERLAY_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_EXFAT_FS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_PSTORE=y
|
||||
# CONFIG_PSTORE_DEFLATE_COMPRESS is not set
|
||||
CONFIG_PSTORE_CONSOLE=y
|
||||
CONFIG_PSTORE_PMSG=y
|
||||
CONFIG_PSTORE_RAM=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITYFS=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_HARDENED_USERCOPY=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
||||
CONFIG_LSM="selinux"
|
||||
CONFIG_CRYPTO_XTS=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_842=y
|
||||
CONFIG_CRYPTO_LZ4=y
|
||||
CONFIG_CRYPTO_LZ4HC=y
|
||||
CONFIG_CRYPTO_ZSTD=y
|
||||
CONFIG_CRYPTO_ANSI_CPRNG=y
|
||||
CONFIG_CRYPTO_USER_API_HASH=y
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=y
|
||||
CONFIG_CRYPTO_USER_API_RNG=y
|
||||
CONFIG_CRYPTO_USER_API_AEAD=y
|
||||
CONFIG_CRYPTO_DEV_QCOM_RNG=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_CMA_SIZE_MBYTES=32
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_PANIC_TIMEOUT=5
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_SCHEDSTATS=y
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
|
|
@ -820,15 +820,20 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = {
|
|||
.num_clks = ARRAY_SIZE(qcs404_clks),
|
||||
};
|
||||
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, ln_bb_clk3_pin, ln_bb_clk3_a_pin,
|
||||
3, 19200000);
|
||||
DEFINE_CLK_SMD_RPM_BRANCH(msm8998, bi_tcxo, bi_tcxo_a, QCOM_SMD_RPM_MISC_CLK, 0,
|
||||
19200000);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, ln_bb_clk3, ln_bb_clk3_a, 3, 19200000);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, ln_bb_clk3_pin, ln_bb_clk3_a_pin, 3, 19200000);
|
||||
DEFINE_CLK_SMD_RPM(msm8998, aggre1_noc_clk, aggre1_noc_a_clk,
|
||||
QCOM_SMD_RPM_AGGR_CLK, 1);
|
||||
DEFINE_CLK_SMD_RPM(msm8998, aggre2_noc_clk, aggre2_noc_a_clk,
|
||||
QCOM_SMD_RPM_AGGR_CLK, 2);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6, 19200000);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6, 19200000);
|
||||
|
||||
static struct clk_smd_rpm *msm8998_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &msm8998_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &msm8998_bi_tcxo_a,
|
||||
[RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
|
||||
[RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk,
|
||||
[RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk,
|
||||
|
|
@ -841,12 +846,22 @@ static struct clk_smd_rpm *msm8998_clks[] = {
|
|||
[RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk,
|
||||
[RPM_SMD_DIV_CLK1] = &msm8974_div_clk1,
|
||||
[RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1,
|
||||
[RPM_SMD_DIV_CLK2] = &msm8974_div_clk2,
|
||||
[RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2,
|
||||
[RPM_SMD_DIV_CLK3] = &msm8992_div_clk3,
|
||||
[RPM_SMD_DIV_A_CLK3] = &msm8992_div_clk3_a,
|
||||
[RPM_SMD_IPA_CLK] = &msm8976_ipa_clk,
|
||||
[RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk,
|
||||
[RPM_SMD_LN_BB_CLK1] = &msm8916_bb_clk1,
|
||||
[RPM_SMD_LN_BB_CLK1_A] = &msm8916_bb_clk1_a,
|
||||
[RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2,
|
||||
[RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a,
|
||||
[RPM_SMD_LN_BB_CLK3] = &msm8998_ln_bb_clk3,
|
||||
[RPM_SMD_LN_BB_CLK3_A] = &msm8998_ln_bb_clk3_a,
|
||||
[RPM_SMD_LN_BB_CLK1_PIN] = &msm8916_bb_clk1_pin,
|
||||
[RPM_SMD_LN_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin,
|
||||
[RPM_SMD_LN_BB_CLK2_PIN] = &msm8916_bb_clk2_pin,
|
||||
[RPM_SMD_LN_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin,
|
||||
[RPM_SMD_LN_BB_CLK3_PIN] = &msm8998_ln_bb_clk3_pin,
|
||||
[RPM_SMD_LN_BB_CLK3_A_PIN] = &msm8998_ln_bb_clk3_a_pin,
|
||||
[RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk,
|
||||
|
|
@ -859,10 +874,14 @@ static struct clk_smd_rpm *msm8998_clks[] = {
|
|||
[RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk,
|
||||
[RPM_SMD_RF_CLK1] = &msm8916_rf_clk1,
|
||||
[RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a,
|
||||
[RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin,
|
||||
[RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin,
|
||||
[RPM_SMD_RF_CLK2] = &msm8916_rf_clk2,
|
||||
[RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a,
|
||||
[RPM_SMD_RF_CLK3] = &msm8998_rf_clk3,
|
||||
[RPM_SMD_RF_CLK3_A] = &msm8998_rf_clk3_a,
|
||||
[RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin,
|
||||
[RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin,
|
||||
[RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin,
|
||||
[RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin,
|
||||
[RPM_SMD_RF_CLK3_PIN] = &msm8998_rf_clk3_pin,
|
||||
[RPM_SMD_RF_CLK3_A_PIN] = &msm8998_rf_clk3_a_pin,
|
||||
};
|
||||
|
|
@ -872,14 +891,9 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8998 = {
|
|||
.num_clks = ARRAY_SIZE(msm8998_clks),
|
||||
};
|
||||
|
||||
DEFINE_CLK_SMD_RPM_BRANCH(sdm660, bi_tcxo, bi_tcxo_a, QCOM_SMD_RPM_MISC_CLK, 0,
|
||||
19200000);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk3, ln_bb_clk3_a, 3, 19200000);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk3_pin, ln_bb_clk3_pin_a, 3, 19200000);
|
||||
|
||||
static struct clk_smd_rpm *sdm660_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
|
||||
[RPM_SMD_XO_CLK_SRC] = &msm8998_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &msm8998_bi_tcxo_a,
|
||||
[RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk,
|
||||
[RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk,
|
||||
[RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk,
|
||||
|
|
@ -906,16 +920,16 @@ static struct clk_smd_rpm *sdm660_clks[] = {
|
|||
[RPM_SMD_LN_BB_A_CLK] = &msm8916_bb_clk1_a,
|
||||
[RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2,
|
||||
[RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a,
|
||||
[RPM_SMD_LN_BB_CLK3] = &sdm660_ln_bb_clk3,
|
||||
[RPM_SMD_LN_BB_CLK3_A] = &sdm660_ln_bb_clk3_a,
|
||||
[RPM_SMD_LN_BB_CLK3] = &msm8998_ln_bb_clk3,
|
||||
[RPM_SMD_LN_BB_CLK3_A] = &msm8998_ln_bb_clk3_a,
|
||||
[RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin,
|
||||
[RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin,
|
||||
[RPM_SMD_LN_BB_CLK1_PIN] = &msm8916_bb_clk1_pin,
|
||||
[RPM_SMD_LN_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin,
|
||||
[RPM_SMD_LN_BB_CLK2_PIN] = &msm8916_bb_clk2_pin,
|
||||
[RPM_SMD_LN_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin,
|
||||
[RPM_SMD_LN_BB_CLK3_PIN] = &sdm660_ln_bb_clk3_pin,
|
||||
[RPM_SMD_LN_BB_CLK3_A_PIN] = &sdm660_ln_bb_clk3_pin_a,
|
||||
[RPM_SMD_LN_BB_CLK3_PIN] = &msm8998_ln_bb_clk3_pin,
|
||||
[RPM_SMD_LN_BB_CLK3_A_PIN] = &msm8998_ln_bb_clk3_a_pin,
|
||||
};
|
||||
|
||||
static const struct rpm_smd_clk_desc rpm_clk_sdm660 = {
|
||||
|
|
@ -924,8 +938,8 @@ static const struct rpm_smd_clk_desc rpm_clk_sdm660 = {
|
|||
};
|
||||
|
||||
static struct clk_smd_rpm *mdm9607_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
|
||||
[RPM_SMD_XO_CLK_SRC] = &msm8998_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &msm8998_bi_tcxo_a,
|
||||
[RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk,
|
||||
[RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk,
|
||||
[RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
|
||||
|
|
@ -946,8 +960,8 @@ static const struct rpm_smd_clk_desc rpm_clk_mdm9607 = {
|
|||
};
|
||||
|
||||
static struct clk_smd_rpm *msm8953_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
|
||||
[RPM_SMD_XO_CLK_SRC] = &msm8998_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &msm8998_bi_tcxo_a,
|
||||
[RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk,
|
||||
[RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk,
|
||||
[RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk,
|
||||
|
|
@ -995,8 +1009,8 @@ DEFINE_CLK_SMD_RPM(sm6125, snoc_lpass_clk, snoc_lpass_a_clk,
|
|||
QCOM_SMD_RPM_BUS_CLK, 5);
|
||||
|
||||
static struct clk_smd_rpm *sm6125_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
|
||||
[RPM_SMD_XO_CLK_SRC] = &msm8998_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &msm8998_bi_tcxo_a,
|
||||
[RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk,
|
||||
[RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk,
|
||||
[RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
|
||||
|
|
@ -1017,8 +1031,8 @@ static struct clk_smd_rpm *sm6125_clks[] = {
|
|||
[RPM_SMD_LN_BB_CLK1_A] = &msm8916_bb_clk1_a,
|
||||
[RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2,
|
||||
[RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a,
|
||||
[RPM_SMD_LN_BB_CLK3] = &sdm660_ln_bb_clk3,
|
||||
[RPM_SMD_LN_BB_CLK3_A] = &sdm660_ln_bb_clk3_a,
|
||||
[RPM_SMD_LN_BB_CLK3] = &msm8998_ln_bb_clk3,
|
||||
[RPM_SMD_LN_BB_CLK3_A] = &msm8998_ln_bb_clk3_a,
|
||||
[RPM_SMD_QUP_CLK] = &sm6125_qup_clk,
|
||||
[RPM_SMD_QUP_A_CLK] = &sm6125_qup_a_clk,
|
||||
[RPM_SMD_MMRT_CLK] = &sm6125_mmrt_clk,
|
||||
|
|
@ -1038,8 +1052,8 @@ static const struct rpm_smd_clk_desc rpm_clk_sm6125 = {
|
|||
|
||||
/* SM6115 */
|
||||
static struct clk_smd_rpm *sm6115_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
|
||||
[RPM_SMD_XO_CLK_SRC] = &msm8998_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &msm8998_bi_tcxo_a,
|
||||
[RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk,
|
||||
[RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk,
|
||||
[RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
|
||||
|
|
@ -1090,8 +1104,8 @@ DEFINE_CLK_SMD_RPM(qcm2290, bimc_gpu_clk, bimc_gpu_a_clk,
|
|||
QCOM_SMD_RPM_MEM_CLK, 2);
|
||||
|
||||
static struct clk_smd_rpm *qcm2290_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
|
||||
[RPM_SMD_XO_CLK_SRC] = &msm8998_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &msm8998_bi_tcxo_a,
|
||||
[RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk,
|
||||
[RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk,
|
||||
[RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
|
||||
|
|
|
|||
|
|
@ -2080,6 +2080,7 @@ static struct clk_branch gcc_bimc_gfx_clk = {
|
|||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_bimc_gfx_clk",
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
|
|
@ -2220,6 +2221,7 @@ static struct clk_rcg2 hmss_gpll0_clk_src = {
|
|||
.name = "hmss_gpll0_clk_src",
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
|
@ -2833,6 +2835,43 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch hlos1_vote_lpass_core_smmu_clk = {
|
||||
.halt_reg = 0x7D010,
|
||||
.clkr = {
|
||||
.enable_reg = 0x7D010,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "hlos1_vote_lpass_core_smmu_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch hlos1_vote_lpass_adsp_smmu_clk = {
|
||||
.halt_reg = 0x7D014,
|
||||
.clkr = {
|
||||
.enable_reg = 0x7D014,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "hlos1_vote_lpass_adsp_smmu_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
|
||||
.halt_reg = 0x8A040,
|
||||
.clkr = {
|
||||
.enable_reg = 0x8A040,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "gcc_mss_q6_bimc_axi_clk",
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc pcie_0_gdsc = {
|
||||
.gdscr = 0x6b004,
|
||||
.gds_hw_ctrl = 0x0,
|
||||
|
|
@ -2863,6 +2902,26 @@ static struct gdsc usb_30_gdsc = {
|
|||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc hlos1_vote_lpass_adsp = {
|
||||
.gdscr = 0x7d034,
|
||||
.gds_hw_ctrl = 0x0,
|
||||
.pd = {
|
||||
.name = "lpass_adsp_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc hlos1_vote_lpass_core = {
|
||||
.gdscr = 0x7d038,
|
||||
.gds_hw_ctrl = 0x0,
|
||||
.pd = {
|
||||
.name = "lpass_core_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = ALWAYS_ON,
|
||||
};
|
||||
|
||||
static struct clk_regmap *gcc_msm8998_clocks[] = {
|
||||
[BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
|
||||
[BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
|
||||
|
|
@ -3036,12 +3095,17 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
|
|||
[GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr,
|
||||
[GCC_MMSS_GPLL0_CLK] = &gcc_mmss_gpll0_clk.clkr,
|
||||
[HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr,
|
||||
[GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
|
||||
[HLOS1_VOTE_LPASS_CORE_SMMU_CLK] = &hlos1_vote_lpass_core_smmu_clk.clkr,
|
||||
[HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] = &hlos1_vote_lpass_adsp_smmu_clk.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *gcc_msm8998_gdscs[] = {
|
||||
[PCIE_0_GDSC] = &pcie_0_gdsc,
|
||||
[UFS_GDSC] = &ufs_gdsc,
|
||||
[USB_30_GDSC] = &usb_30_gdsc,
|
||||
[LPASS_ADSP_GDSC] = &hlos1_vote_lpass_adsp,
|
||||
[LPASS_CORE_GDSC] = &hlos1_vote_lpass_core,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_msm8998_resets[] = {
|
||||
|
|
@ -3191,6 +3255,14 @@ static int gcc_msm8998_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* GCC_MMSS_MISC - GCC_GPU_MISC:
|
||||
* 1. Disable the GPLL0 active input to MMSS and GPU
|
||||
* 2. Select clk division 1 (CLK/2)
|
||||
*/
|
||||
regmap_write(regmap, 0x0902C, 0x10003); /* MMSS*/
|
||||
regmap_write(regmap, 0x71028, 0x10003); /* GPU */
|
||||
|
||||
return qcom_cc_really_probe(pdev, &gcc_msm8998_desc, regmap);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -136,11 +136,15 @@ 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,sc7180", },
|
||||
{ .compatible = "qcom,sc7280", },
|
||||
{ .compatible = "qcom,sc8180x", },
|
||||
{ .compatible = "qcom,sdm630", },
|
||||
{ .compatible = "qcom,sdm636", },
|
||||
{ .compatible = "qcom,sdm660", },
|
||||
{ .compatible = "qcom,sdm845", },
|
||||
{ .compatible = "qcom,sm6350", },
|
||||
{ .compatible = "qcom,sm8150", },
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -111,7 +111,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
|
||||
|
|
|
|||
|
|
@ -122,6 +122,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);
|
||||
|
|
@ -153,13 +195,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) {
|
||||
|
|
@ -563,8 +609,12 @@ static void a5xx_ucode_check_version(struct a5xx_gpu *a5xx_gpu,
|
|||
* has been patched. The actual version is in dword [3] but we only care
|
||||
* about the patchlevel which is the lowest nibble of dword [3]
|
||||
*/
|
||||
if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1)
|
||||
if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) {
|
||||
pr_err("adreno HAS WHEREAMI!\n");
|
||||
a5xx_gpu->has_whereami = true;
|
||||
} else {
|
||||
pr_err("adreno has no whereami support\n");
|
||||
}
|
||||
|
||||
msm_gem_put_vaddr(obj);
|
||||
}
|
||||
|
|
@ -936,6 +986,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 +1735,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,
|
||||
|
|
@ -1705,6 +1770,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];
|
||||
|
|
|
|||
|
|
@ -338,6 +338,10 @@ 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/a508_zap.mdt");
|
||||
MODULE_FIRMWARE("qcom/a508_zap.b00");
|
||||
MODULE_FIRMWARE("qcom/a508_zap.b01");
|
||||
MODULE_FIRMWARE("qcom/a508_zap.b02");
|
||||
MODULE_FIRMWARE("qcom/a630_sqe.fw");
|
||||
MODULE_FIRMWARE("qcom/a630_gmu.bin");
|
||||
MODULE_FIRMWARE("qcom/a630_zap.mbn");
|
||||
|
|
|
|||
|
|
@ -682,6 +682,9 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done(
|
|||
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
|
||||
return 0;
|
||||
|
||||
if (phys_enc->hw_ctl->ops.is_started)
|
||||
return dpu_encoder_phys_cmd_wait_for_tx_complete(phys_enc);
|
||||
|
||||
return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\
|
||||
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
|
||||
|
||||
#define VIG_MSM8998_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
|
||||
|
||||
#define VIG_SDM845_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
|
||||
|
||||
|
|
@ -25,6 +28,11 @@
|
|||
#define VIG_SM8250_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
|
||||
|
||||
#define DMA_MSM8998_MASK \
|
||||
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
|
||||
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
|
||||
BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
|
||||
|
||||
#define DMA_SDM845_MASK \
|
||||
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
|
||||
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
|
||||
|
|
@ -33,6 +41,9 @@
|
|||
#define DMA_CURSOR_SDM845_MASK \
|
||||
(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
|
||||
|
||||
#define DMA_CURSOR_MSM8998_MASK \
|
||||
(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
|
||||
|
||||
#define MIXER_SDM845_MASK \
|
||||
(BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
|
||||
|
||||
|
|
@ -49,6 +60,8 @@
|
|||
|
||||
#define MERGE_3D_SM8150_MASK (0)
|
||||
|
||||
#define DSPP_MSM8998_MASK BIT(DPU_DSPP_PCC) | BIT(DPU_DSPP_GC)
|
||||
|
||||
#define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
|
||||
|
||||
#define INTF_SDM845_MASK (0)
|
||||
|
|
@ -181,6 +194,22 @@ static const uint32_t plane_formats_yuv[] = {
|
|||
* DPU sub blocks config
|
||||
*************************************************************/
|
||||
/* DPU top level caps */
|
||||
static const struct dpu_caps msm8998_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x7,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V1,
|
||||
.ubwc_version = DPU_HW_UBWC_VER_10,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
.has_idle_pc = true,
|
||||
.has_3d_merge = true,
|
||||
.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
|
||||
.max_hdeci_exp = MAX_HORZ_DECIMATION,
|
||||
.max_vdeci_exp = MAX_VERT_DECIMATION,
|
||||
};
|
||||
|
||||
static const struct dpu_caps sdm845_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
|
|
@ -251,6 +280,35 @@ static const struct dpu_caps sc7280_dpu_caps = {
|
|||
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
|
||||
};
|
||||
|
||||
static const struct dpu_mdp_cfg msm8998_mdp[] = {
|
||||
{
|
||||
.name = "top_0", .id = MDP_TOP,
|
||||
.base = 0x0, .len = 0x458,
|
||||
.features = 0,
|
||||
.highest_bank_bit = 0x2,
|
||||
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
|
||||
.reg_off = 0x2AC, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_VIG1] = {
|
||||
.reg_off = 0x2B4, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_VIG2] = {
|
||||
.reg_off = 0x2BC, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_VIG3] = {
|
||||
.reg_off = 0x2C4, .bit_off = 0},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA0] = {
|
||||
.reg_off = 0x2AC, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
|
||||
.reg_off = 0x2B4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
|
||||
.reg_off = 0x2C4, .bit_off = 8},
|
||||
.clk_ctrls[DPU_CLK_CTRL_DMA3] = {
|
||||
.reg_off = 0x2C4, .bit_off = 12},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
|
||||
.reg_off = 0x3A8, .bit_off = 15},
|
||||
.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
|
||||
.reg_off = 0x3B0, .bit_off = 15},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_mdp_cfg sdm845_mdp[] = {
|
||||
{
|
||||
.name = "top_0", .id = MDP_TOP,
|
||||
|
|
@ -339,6 +397,39 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = {
|
|||
/*************************************************************
|
||||
* CTL sub blocks config
|
||||
*************************************************************/
|
||||
static const struct dpu_ctl_cfg msm8998_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x1000, .len = 0x94,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
},
|
||||
{
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x1200, .len = 0x94,
|
||||
.features = 0,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
},
|
||||
{
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
.base = 0x1400, .len = 0x94,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
|
||||
},
|
||||
{
|
||||
.name = "ctl_3", .id = CTL_3,
|
||||
.base = 0x1600, .len = 0x94,
|
||||
.features = 0,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
|
||||
},
|
||||
{
|
||||
.name = "ctl_4", .id = CTL_4,
|
||||
.base = 0x1800, .len = 0x94,
|
||||
.features = 0,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_ctl_cfg sdm845_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
|
|
@ -497,6 +588,15 @@ static const struct dpu_ctl_cfg sc7280_ctl[] = {
|
|||
.virt_num_formats = ARRAY_SIZE(plane_formats), \
|
||||
}
|
||||
|
||||
static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 =
|
||||
_VIG_SBLK("0", 0, DPU_SSPP_SCALER_QSEED3);
|
||||
static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 =
|
||||
_VIG_SBLK("1", 0, DPU_SSPP_SCALER_QSEED3);
|
||||
static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 =
|
||||
_VIG_SBLK("2", 0, DPU_SSPP_SCALER_QSEED3);
|
||||
static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 =
|
||||
_VIG_SBLK("3", 0, DPU_SSPP_SCALER_QSEED3);
|
||||
|
||||
static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 =
|
||||
_VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3);
|
||||
static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 =
|
||||
|
|
@ -523,6 +623,25 @@ static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4);
|
|||
.clk_ctrl = _clkctrl \
|
||||
}
|
||||
|
||||
static const struct dpu_sspp_cfg msm8998_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_MSM8998_MASK,
|
||||
msm8998_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_MSM8998_MASK,
|
||||
msm8998_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_MSM8998_MASK,
|
||||
msm8998_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_MSM8998_MASK,
|
||||
msm8998_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_MSM8998_MASK,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_MSM8998_MASK,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_MSM8998_MASK,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_MSM8998_MASK,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_cfg sdm845_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
|
||||
sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
|
||||
|
|
@ -599,17 +718,6 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = {
|
|||
* MIXER sub blocks config
|
||||
*************************************************************/
|
||||
|
||||
/* SDM845 */
|
||||
|
||||
static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
|
||||
.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.maxblendstages = 11, /* excluding base layer */
|
||||
.blendstage_base = { /* offsets relative to mixer base */
|
||||
0x20, 0x38, 0x50, 0x68, 0x80, 0x98,
|
||||
0xb0, 0xc8, 0xe0, 0xf8, 0x110
|
||||
},
|
||||
};
|
||||
|
||||
#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \
|
||||
{ \
|
||||
.name = _name, .id = _id, \
|
||||
|
|
@ -621,6 +729,43 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
|
|||
.dspp = _dspp \
|
||||
}
|
||||
|
||||
/* MSM8998 */
|
||||
|
||||
static const struct dpu_lm_sub_blks msm8998_lm_sblk = {
|
||||
.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.maxblendstages = 7, /* excluding base layer */
|
||||
.blendstage_base = { /* offsets relative to mixer base */
|
||||
0x20, 0x50, 0x80, 0xb0, 0x230,
|
||||
0x260, 0x290
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_lm_cfg msm8998_lm[] = {
|
||||
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
|
||||
&msm8998_lm_sblk, PINGPONG_0, LM_2, DSPP_0),
|
||||
LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
|
||||
&msm8998_lm_sblk, PINGPONG_1, LM_5, DSPP_1),
|
||||
LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
|
||||
&msm8998_lm_sblk, PINGPONG_2, LM_0, 0),
|
||||
LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK,
|
||||
&msm8998_lm_sblk, PINGPONG_MAX, 0, 0),
|
||||
LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK,
|
||||
&msm8998_lm_sblk, PINGPONG_MAX, 0, 0),
|
||||
LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
|
||||
&msm8998_lm_sblk, PINGPONG_3, LM_1, 0),
|
||||
};
|
||||
|
||||
/* SDM845 */
|
||||
|
||||
static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
|
||||
.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.maxblendstages = 11, /* excluding base layer */
|
||||
.blendstage_base = { /* offsets relative to mixer base */
|
||||
0x20, 0x38, 0x50, 0x68, 0x80, 0x98,
|
||||
0xb0, 0xc8, 0xe0, 0xf8, 0x110
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_lm_cfg sdm845_lm[] = {
|
||||
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
|
||||
&sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
|
||||
|
|
@ -682,6 +827,13 @@ static const struct dpu_lm_cfg sc7280_lm[] = {
|
|||
/*************************************************************
|
||||
* DSPP sub blocks config
|
||||
*************************************************************/
|
||||
static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = {
|
||||
.pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
|
||||
.len = 0x90, .version = 0x10007},
|
||||
.gc = { .id = DPU_DSPP_GC, .base = 0x17c0,
|
||||
.len = 0x90, .version = 0x10007},
|
||||
};
|
||||
|
||||
static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = {
|
||||
.pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
|
||||
.len = 0x90, .version = 0x10000},
|
||||
|
|
@ -700,6 +852,13 @@ static const struct dpu_dspp_sub_blks sm8150_dspp_sblk = {
|
|||
.sblk = _sblk \
|
||||
}
|
||||
|
||||
static const struct dpu_dspp_cfg msm8998_dspp[] = {
|
||||
DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK,
|
||||
&msm8998_dspp_sblk),
|
||||
DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_MSM8998_MASK,
|
||||
&msm8998_dspp_sblk),
|
||||
};
|
||||
|
||||
static const struct dpu_dspp_cfg sc7180_dspp[] = {
|
||||
DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK,
|
||||
&sc7180_dspp_sblk),
|
||||
|
|
@ -836,6 +995,13 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = {
|
|||
.intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
|
||||
}
|
||||
|
||||
static const struct dpu_intf_cfg msm8998_intf[] = {
|
||||
INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
|
||||
INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
|
||||
INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
|
||||
INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
|
||||
};
|
||||
|
||||
static const struct dpu_intf_cfg sdm845_intf[] = {
|
||||
INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
|
||||
INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
|
||||
|
|
@ -865,9 +1031,55 @@ static const struct dpu_intf_cfg sc7280_intf[] = {
|
|||
* VBIF sub blocks config
|
||||
*************************************************************/
|
||||
/* VBIF QOS remap */
|
||||
static const u32 msm8998_rt_pri_lvl[] = {1, 2, 2, 2};
|
||||
static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1};
|
||||
static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
|
||||
static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3};
|
||||
|
||||
static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = {
|
||||
{
|
||||
.pps = 1088 * 1920 * 30,
|
||||
.ot_limit = 2,
|
||||
},
|
||||
{
|
||||
.pps = 1088 * 1920 * 60,
|
||||
.ot_limit = 6,
|
||||
},
|
||||
{
|
||||
.pps = 3840 * 2160 * 30,
|
||||
.ot_limit = 16,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_vbif_cfg msm8998_vbif[] = {
|
||||
{
|
||||
.name = "vbif_0", .id = VBIF_0,
|
||||
.base = 0, .len = 0x1040,
|
||||
.default_ot_rd_limit = 32,
|
||||
.default_ot_wr_limit = 32,
|
||||
.features = BIT(DPU_VBIF_QOS_REMAP) | BIT(DPU_VBIF_QOS_OTLIM),
|
||||
.xin_halt_timeout = 0x4000,
|
||||
.dynamic_ot_rd_tbl = {
|
||||
.count = ARRAY_SIZE(msm8998_ot_rdwr_cfg),
|
||||
.cfg = msm8998_ot_rdwr_cfg,
|
||||
},
|
||||
.dynamic_ot_wr_tbl = {
|
||||
.count = ARRAY_SIZE(msm8998_ot_rdwr_cfg),
|
||||
.cfg = msm8998_ot_rdwr_cfg,
|
||||
},
|
||||
.qos_rt_tbl = {
|
||||
.npriority_lvl = ARRAY_SIZE(msm8998_rt_pri_lvl),
|
||||
.priority_lvl = msm8998_rt_pri_lvl,
|
||||
},
|
||||
.qos_nrt_tbl = {
|
||||
.npriority_lvl = ARRAY_SIZE(msm8998_nrt_pri_lvl),
|
||||
.priority_lvl = msm8998_nrt_pri_lvl,
|
||||
},
|
||||
.memtype_count = 14,
|
||||
.memtype = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_vbif_cfg sdm845_vbif[] = {
|
||||
{
|
||||
.name = "vbif_0", .id = VBIF_0,
|
||||
|
|
@ -908,6 +1120,22 @@ static const struct dpu_reg_dma_cfg sm8250_regdma = {
|
|||
*************************************************************/
|
||||
|
||||
/* SSPP QOS LUTs */
|
||||
static const struct dpu_qos_lut_entry msm8998_qos_linear[] = {
|
||||
{.fl = 4, .lut = 0x1b},
|
||||
{.fl = 5, .lut = 0x5b},
|
||||
{.fl = 6, .lut = 0x15b},
|
||||
{.fl = 7, .lut = 0x55b},
|
||||
{.fl = 8, .lut = 0x155b},
|
||||
{.fl = 9, .lut = 0x555b},
|
||||
{.fl = 10, .lut = 0x1555b},
|
||||
{.fl = 11, .lut = 0x5555b},
|
||||
{.fl = 12, .lut = 0x15555b},
|
||||
{.fl = 13, .lut = 0x55555b},
|
||||
{.fl = 14, .lut = 0},
|
||||
{.fl = 1, .lut = 0x1b},
|
||||
{.fl = 0, .lut = 0}
|
||||
};
|
||||
|
||||
static const struct dpu_qos_lut_entry sdm845_qos_linear[] = {
|
||||
{.fl = 4, .lut = 0x357},
|
||||
{.fl = 5, .lut = 0x3357},
|
||||
|
|
@ -923,6 +1151,15 @@ static const struct dpu_qos_lut_entry sdm845_qos_linear[] = {
|
|||
{.fl = 0, .lut = 0x11222222223357}
|
||||
};
|
||||
|
||||
static const struct dpu_qos_lut_entry msm8998_qos_macrotile[] = {
|
||||
{.fl = 10, .lut = 0x1aaff},
|
||||
{.fl = 11, .lut = 0x5aaff},
|
||||
{.fl = 12, .lut = 0x15aaff},
|
||||
{.fl = 13, .lut = 0x55aaff},
|
||||
{.fl = 1, .lut = 0x1aaff},
|
||||
{.fl = 0, .lut = 0},
|
||||
};
|
||||
|
||||
static const struct dpu_qos_lut_entry sc7180_qos_linear[] = {
|
||||
{.fl = 0, .lut = 0x0011222222335777},
|
||||
};
|
||||
|
|
@ -944,6 +1181,10 @@ static const struct dpu_qos_lut_entry sc7180_qos_macrotile[] = {
|
|||
{.fl = 0, .lut = 0x0011223344556677},
|
||||
};
|
||||
|
||||
static const struct dpu_qos_lut_entry msm8998_qos_nrt[] = {
|
||||
{.fl = 0, .lut = 0x0},
|
||||
};
|
||||
|
||||
static const struct dpu_qos_lut_entry sdm845_qos_nrt[] = {
|
||||
{.fl = 0, .lut = 0x0},
|
||||
};
|
||||
|
|
@ -952,6 +1193,42 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
|
|||
{.fl = 0, .lut = 0x0},
|
||||
};
|
||||
|
||||
static const struct dpu_perf_cfg msm8998_perf_data = {
|
||||
.max_bw_low = 6700000,
|
||||
.max_bw_high = 6700000,
|
||||
.min_core_ib = 2400000,
|
||||
.min_llcc_ib = 800000,
|
||||
.min_dram_ib = 800000,
|
||||
.undersized_prefill_lines = 2,
|
||||
.xtra_prefill_lines = 2,
|
||||
.dest_scale_prefill_lines = 3,
|
||||
.macrotile_prefill_lines = 4,
|
||||
.yuv_nv12_prefill_lines = 8,
|
||||
.linear_prefill_lines = 1,
|
||||
.downscaling_prefill_lines = 1,
|
||||
.amortizable_threshold = 25,
|
||||
.min_prefill_lines = 25,
|
||||
.danger_lut_tbl = {0xf, 0xffff, 0x0},
|
||||
.safe_lut_tbl = {0xfffc, 0xff00, 0xffff},
|
||||
.qos_lut_tbl = {
|
||||
{.nentry = ARRAY_SIZE(msm8998_qos_linear),
|
||||
.entries = msm8998_qos_linear
|
||||
},
|
||||
{.nentry = ARRAY_SIZE(msm8998_qos_macrotile),
|
||||
.entries = msm8998_qos_macrotile
|
||||
},
|
||||
{.nentry = ARRAY_SIZE(msm8998_qos_nrt),
|
||||
.entries = msm8998_qos_nrt
|
||||
},
|
||||
},
|
||||
.cdp_cfg = {
|
||||
{.rd_enable = 1, .wr_enable = 1},
|
||||
{.rd_enable = 1, .wr_enable = 0}
|
||||
},
|
||||
.clk_inefficiency_factor = 200,
|
||||
.bw_inefficiency_factor = 120,
|
||||
};
|
||||
|
||||
static const struct dpu_perf_cfg sdm845_perf_data = {
|
||||
.max_bw_low = 6800000,
|
||||
.max_bw_high = 6800000,
|
||||
|
|
@ -1106,6 +1383,34 @@ static const struct dpu_perf_cfg sc7280_perf_data = {
|
|||
* Hardware catalog init
|
||||
*************************************************************/
|
||||
|
||||
/*
|
||||
* msm8998_cfg_init(): populate sdm845 dpu sub-blocks reg offsets
|
||||
* and instance counts.
|
||||
*/
|
||||
static void msm8998_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
|
||||
{
|
||||
*dpu_cfg = (struct dpu_mdss_cfg){
|
||||
.caps = &msm8998_dpu_caps,
|
||||
.mdp_count = ARRAY_SIZE(msm8998_mdp),
|
||||
.mdp = msm8998_mdp,
|
||||
.ctl_count = ARRAY_SIZE(msm8998_ctl),
|
||||
.ctl = msm8998_ctl,
|
||||
.sspp_count = ARRAY_SIZE(msm8998_sspp),
|
||||
.sspp = msm8998_sspp,
|
||||
.mixer_count = ARRAY_SIZE(msm8998_lm),
|
||||
.mixer = msm8998_lm,
|
||||
.pingpong_count = ARRAY_SIZE(sdm845_pp),
|
||||
.pingpong = sdm845_pp,
|
||||
.intf_count = ARRAY_SIZE(msm8998_intf),
|
||||
.intf = msm8998_intf,
|
||||
.vbif_count = ARRAY_SIZE(msm8998_vbif),
|
||||
.vbif = msm8998_vbif,
|
||||
.reg_dma_count = 0,
|
||||
.perf = msm8998_perf_data,
|
||||
.mdss_irqs = IRQ_SM8250_MASK,
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets
|
||||
* and instance counts.
|
||||
|
|
@ -1256,6 +1561,8 @@ static void sc7280_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
|
|||
}
|
||||
|
||||
static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
|
||||
{ .hw_rev = DPU_HW_VER_300, .cfg_init = msm8998_cfg_init},
|
||||
{ .hw_rev = DPU_HW_VER_301, .cfg_init = msm8998_cfg_init},
|
||||
{ .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init},
|
||||
{ .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init},
|
||||
{ .hw_rev = DPU_HW_VER_500, .cfg_init = sm8150_cfg_init},
|
||||
|
|
|
|||
|
|
@ -432,6 +432,8 @@ enum dpu_clk_ctrl_type {
|
|||
DPU_CLK_CTRL_RGB3,
|
||||
DPU_CLK_CTRL_DMA0,
|
||||
DPU_CLK_CTRL_DMA1,
|
||||
DPU_CLK_CTRL_DMA2,
|
||||
DPU_CLK_CTRL_DMA3,
|
||||
DPU_CLK_CTRL_CURSOR0,
|
||||
DPU_CLK_CTRL_CURSOR1,
|
||||
DPU_CLK_CTRL_INLINE_ROT0_SSPP,
|
||||
|
|
|
|||
|
|
@ -91,6 +91,11 @@ static inline void dpu_hw_ctl_trigger_start(struct dpu_hw_ctl *ctx)
|
|||
DPU_REG_WRITE(&ctx->hw, CTL_START, 0x1);
|
||||
}
|
||||
|
||||
static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx)
|
||||
{
|
||||
return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0));
|
||||
}
|
||||
|
||||
static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx)
|
||||
{
|
||||
trace_dpu_hw_ctl_trigger_prepare(ctx->pending_flush_mask,
|
||||
|
|
@ -579,6 +584,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
|
|||
ops->get_pending_flush = dpu_hw_ctl_get_pending_flush;
|
||||
ops->get_flush_register = dpu_hw_ctl_get_flush_register;
|
||||
ops->trigger_start = dpu_hw_ctl_trigger_start;
|
||||
ops->is_started = dpu_hw_ctl_is_started;
|
||||
ops->trigger_pending = dpu_hw_ctl_trigger_pending;
|
||||
ops->reset = dpu_hw_ctl_reset_control;
|
||||
ops->wait_reset_status = dpu_hw_ctl_wait_reset_status;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,13 @@ struct dpu_hw_ctl_ops {
|
|||
*/
|
||||
void (*trigger_start)(struct dpu_hw_ctl *ctx);
|
||||
|
||||
/**
|
||||
* check if the ctl is started
|
||||
* @ctx : ctl path ctx pointer
|
||||
* @Return: true if started, false if stopped
|
||||
*/
|
||||
bool (*is_started)(struct dpu_hw_ctl *ctx);
|
||||
|
||||
/**
|
||||
* kickoff prepare is in progress hw operation for sw
|
||||
* controlled interfaces: DSI cmd mode and WB interface
|
||||
|
|
|
|||
|
|
@ -1286,6 +1286,7 @@ static const struct dev_pm_ops dpu_pm_ops = {
|
|||
};
|
||||
|
||||
static const struct of_device_id dpu_dt_match[] = {
|
||||
{ .compatible = "qcom,msm8998-dpu", },
|
||||
{ .compatible = "qcom,sdm845-dpu", },
|
||||
{ .compatible = "qcom,sc7180-dpu", },
|
||||
{ .compatible = "qcom,sc7280-dpu", },
|
||||
|
|
|
|||
|
|
@ -1038,13 +1038,12 @@ static const struct mdp5_cfg_hw sdm630_config = {
|
|||
.mdp = {
|
||||
.count = 1,
|
||||
.caps = MDP_CAP_CDM |
|
||||
MDP_CAP_SRC_SPLIT |
|
||||
0,
|
||||
},
|
||||
.ctl = {
|
||||
.count = 5,
|
||||
.base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
|
||||
.flush_hw_mask = 0xf4ffffff,
|
||||
.flush_hw_mask = 0xf54338c1,
|
||||
},
|
||||
.pipe_vig = {
|
||||
.count = 1,
|
||||
|
|
@ -1057,16 +1056,6 @@ static const struct mdp5_cfg_hw sdm630_config = {
|
|||
MDP_PIPE_CAP_SW_PIX_EXT |
|
||||
0,
|
||||
},
|
||||
.pipe_rgb = {
|
||||
.count = 4,
|
||||
.base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
|
||||
.caps = MDP_PIPE_CAP_HFLIP |
|
||||
MDP_PIPE_CAP_VFLIP |
|
||||
MDP_PIPE_CAP_SCALE |
|
||||
MDP_PIPE_CAP_DECIMATION |
|
||||
MDP_PIPE_CAP_SW_PIX_EXT |
|
||||
0,
|
||||
},
|
||||
.pipe_dma = {
|
||||
.count = 2, /* driver supports max of 2 currently */
|
||||
.base = { 0x24000, 0x26000, 0x28000 },
|
||||
|
|
@ -1086,13 +1075,12 @@ static const struct mdp5_cfg_hw sdm630_config = {
|
|||
},
|
||||
|
||||
.lm = {
|
||||
.count = 2,
|
||||
.base = { 0x44000, 0x46000 },
|
||||
.count = 3, /* LM_1 seems broken */
|
||||
.base = { 0x44000, 0x45000, 0x46000 },
|
||||
.instances = {
|
||||
{ .id = 0, .pp = 0, .dspp = 0,
|
||||
.caps = MDP_LM_CAP_DISPLAY |
|
||||
MDP_LM_CAP_PAIR, },
|
||||
{ .id = 1, .pp = 1, .dspp = -1,
|
||||
.caps = MDP_LM_CAP_DISPLAY, },
|
||||
{ .id = 2, .pp = 2, .dspp = -1,
|
||||
.caps = MDP_LM_CAP_WB, },
|
||||
},
|
||||
.nb_stages = 8,
|
||||
|
|
@ -1108,8 +1096,8 @@ static const struct mdp5_cfg_hw sdm630_config = {
|
|||
.base = { 0x78000, 0x78800 },
|
||||
},
|
||||
.pp = {
|
||||
.count = 3,
|
||||
.base = { 0x70000, 0x71000, 0x72000 },
|
||||
.count = 3, /* Do not use PP1 */
|
||||
.base = { 0x70000, 0x70800, 0x71000 },
|
||||
},
|
||||
.cdm = {
|
||||
.count = 1,
|
||||
|
|
@ -1137,11 +1125,11 @@ static const struct mdp5_cfg_hw sdm660_config = {
|
|||
.ctl = {
|
||||
.count = 5,
|
||||
.base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
|
||||
.flush_hw_mask = 0xf4ffffff,
|
||||
.flush_hw_mask = 0xf5437bc3,
|
||||
},
|
||||
.pipe_vig = {
|
||||
.count = 2,
|
||||
.base = { 0x04000, 0x6000 },
|
||||
.base = { 0x04000, 0x06000 },
|
||||
.caps = MDP_PIPE_CAP_HFLIP |
|
||||
MDP_PIPE_CAP_VFLIP |
|
||||
MDP_PIPE_CAP_SCALE |
|
||||
|
|
@ -1150,16 +1138,6 @@ static const struct mdp5_cfg_hw sdm660_config = {
|
|||
MDP_PIPE_CAP_SW_PIX_EXT |
|
||||
0,
|
||||
},
|
||||
.pipe_rgb = {
|
||||
.count = 4,
|
||||
.base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
|
||||
.caps = MDP_PIPE_CAP_HFLIP |
|
||||
MDP_PIPE_CAP_VFLIP |
|
||||
MDP_PIPE_CAP_SCALE |
|
||||
MDP_PIPE_CAP_DECIMATION |
|
||||
MDP_PIPE_CAP_SW_PIX_EXT |
|
||||
0,
|
||||
},
|
||||
.pipe_dma = {
|
||||
.count = 2, /* driver supports max of 2 currently */
|
||||
.base = { 0x24000, 0x26000, 0x28000 },
|
||||
|
|
@ -1179,19 +1157,19 @@ static const struct mdp5_cfg_hw sdm660_config = {
|
|||
},
|
||||
|
||||
.lm = {
|
||||
.count = 4,
|
||||
.base = { 0x44000, 0x45000, 0x46000, 0x49000 },
|
||||
.count = 6, /* Do not use LM_3, LM_4 */
|
||||
.base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
|
||||
.instances = {
|
||||
{ .id = 0, .pp = 0, .dspp = 0,
|
||||
.caps = MDP_LM_CAP_DISPLAY |
|
||||
MDP_LM_CAP_PAIR, },
|
||||
{ .id = 1, .pp = 1, .dspp = 1,
|
||||
.caps = MDP_LM_CAP_DISPLAY, },
|
||||
{ .id = 2, .pp = 2, .dspp = -1,
|
||||
{ .id = 2, .pp = -1, .dspp = -1,
|
||||
.caps = MDP_LM_CAP_WB, },
|
||||
{ .id = 5, .pp = 4, .dspp = -1,
|
||||
.caps = MDP_LM_CAP_DISPLAY |
|
||||
MDP_LM_CAP_PAIR, },
|
||||
{ .id = 3, .pp = 3, .dspp = -1,
|
||||
.caps = MDP_LM_CAP_WB, },
|
||||
},
|
||||
.nb_stages = 8,
|
||||
.max_width = 2560,
|
||||
|
|
@ -1206,7 +1184,7 @@ static const struct mdp5_cfg_hw sdm660_config = {
|
|||
.base = { 0x78000, 0x78800 },
|
||||
},
|
||||
.pp = {
|
||||
.count = 5,
|
||||
.count = 5, /* Do not use PP_2 and PP_3 */
|
||||
.base = { 0x70000, 0x70800, 0x71000, 0x71800, 0x72000 },
|
||||
},
|
||||
.cdm = {
|
||||
|
|
@ -1220,10 +1198,10 @@ static const struct mdp5_cfg_hw sdm660_config = {
|
|||
.intf = {
|
||||
.base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800 },
|
||||
.connect = {
|
||||
[0] = INTF_DISABLED,
|
||||
[0] = INTF_HDMI,
|
||||
[1] = INTF_DSI,
|
||||
[2] = INTF_DSI,
|
||||
[3] = INTF_HDMI,
|
||||
[3] = INTF_DISABLED,
|
||||
},
|
||||
},
|
||||
.max_clk = 412500000,
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ struct mdp5_crtc {
|
|||
|
||||
struct completion pp_completion;
|
||||
|
||||
atomic_t pp_complete;
|
||||
|
||||
bool lm_cursor_enabled;
|
||||
|
||||
struct {
|
||||
|
|
@ -83,6 +85,9 @@ static void request_pending(struct drm_crtc *crtc, uint32_t pending)
|
|||
static void request_pp_done_pending(struct drm_crtc *crtc)
|
||||
{
|
||||
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
||||
|
||||
atomic_set(&mdp5_crtc->pp_complete, 0);
|
||||
|
||||
reinit_completion(&mdp5_crtc->pp_completion);
|
||||
}
|
||||
|
||||
|
|
@ -1195,6 +1200,15 @@ static void mdp5_crtc_pp_done_irq(struct mdp_irq *irq, uint32_t irqstatus)
|
|||
{
|
||||
struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc,
|
||||
pp_done);
|
||||
struct drm_crtc *crtc = &mdp5_crtc->base;
|
||||
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
|
||||
|
||||
atomic_set(&mdp5_crtc->pp_complete, 1);
|
||||
|
||||
if (mdp5_cstate->cmd_mode) {
|
||||
struct mdp5_ctl *ctl = mdp5_cstate->ctl;
|
||||
mdp5_ctl_commit_finished(ctl);
|
||||
}
|
||||
|
||||
complete_all(&mdp5_crtc->pp_completion);
|
||||
}
|
||||
|
|
@ -1206,6 +1220,9 @@ static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc)
|
|||
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
|
||||
int ret;
|
||||
|
||||
if (atomic_read(&mdp5_crtc->pp_complete))
|
||||
return;
|
||||
|
||||
ret = wait_for_completion_timeout(&mdp5_crtc->pp_completion,
|
||||
msecs_to_jiffies(50));
|
||||
if (ret == 0)
|
||||
|
|
@ -1319,6 +1336,7 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
|
|||
spin_lock_init(&mdp5_crtc->lm_lock);
|
||||
spin_lock_init(&mdp5_crtc->cursor.lock);
|
||||
init_completion(&mdp5_crtc->pp_completion);
|
||||
atomic_set(&mdp5_crtc->pp_complete, 0);
|
||||
|
||||
mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq;
|
||||
mdp5_crtc->err.irq = mdp5_crtc_err_irq;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ struct mdp5_ctl {
|
|||
/* True if the current CTL has FLUSH bits pending for single FLUSH. */
|
||||
bool flush_pending;
|
||||
|
||||
bool busy;
|
||||
|
||||
struct mdp5_ctl *pair; /* Paired CTL to be flushed together */
|
||||
};
|
||||
|
||||
|
|
@ -209,6 +211,11 @@ static void send_start_signal(struct mdp5_ctl *ctl)
|
|||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctl->hw_lock, flags);
|
||||
if (ctl->busy) {
|
||||
spin_unlock_irqrestore(&ctl->hw_lock, flags);
|
||||
return;
|
||||
}
|
||||
ctl->busy = true;
|
||||
ctl_write(ctl, REG_MDP5_CTL_START(ctl->id), 1);
|
||||
spin_unlock_irqrestore(&ctl->hw_lock, flags);
|
||||
}
|
||||
|
|
@ -242,6 +249,11 @@ int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void mdp5_ctl_commit_finished(struct mdp5_ctl *ctl)
|
||||
{
|
||||
ctl->busy = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* CTL registers need to be flushed after calling this function
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ u32 mdp_ctl_flush_mask_cursor(int cursor_id);
|
|||
u32 mdp_ctl_flush_mask_encoder(struct mdp5_interface *intf);
|
||||
|
||||
/* @flush_mask: see CTL flush masks definitions below */
|
||||
void mdp5_ctl_commit_finished(struct mdp5_ctl *ctl);
|
||||
u32 mdp5_ctl_commit(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline,
|
||||
u32 flush_mask, bool start);
|
||||
u32 mdp5_ctl_get_commit_status(struct mdp5_ctl *ctl);
|
||||
|
|
|
|||
|
|
@ -110,7 +110,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);
|
||||
|
|
@ -428,12 +428,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);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,17 @@ config DRM_PANEL_ASUS_Z00T_TM5P5_NT35596
|
|||
NT35596 1080x1920 video mode panel as found in some Asus
|
||||
Zenfone 2 Laser Z00T devices.
|
||||
|
||||
config DRM_PANEL_BOE_BF060Y8M_AJ0
|
||||
tristate "Boe BF060Y8M-AJ0 panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
Say Y here if you want to enable support for Boe BF060Y8M-AJ0
|
||||
5.99" AMOLED modules. The panel has a 1080x2160 resolution and
|
||||
uses 24 bit RGB per pixel. It provides a MIPI DSI interface to
|
||||
the host and backlight is controlled through DSI commands.
|
||||
|
||||
config DRM_PANEL_BOE_HIMAX8279D
|
||||
tristate "Boe Himax8279d panel"
|
||||
depends on OF
|
||||
|
|
@ -272,6 +283,17 @@ config DRM_PANEL_NOVATEK_NT35510
|
|||
around the Novatek NT35510 display controller, such as some
|
||||
Hydis panels.
|
||||
|
||||
config DRM_PANEL_NOVATEK_NT35950
|
||||
tristate "Novatek NT35950 DSI panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
Say Y here if you want to enable support for the panels built
|
||||
around the Novatek NT35950 display controller, such as some
|
||||
Sharp panels used in Sony Xperia Z5 Premium and XZ Premium
|
||||
mobile phones.
|
||||
|
||||
config DRM_PANEL_NOVATEK_NT36672A
|
||||
tristate "Novatek NT36672A DSI panel"
|
||||
depends on OF
|
||||
|
|
@ -416,6 +438,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
|
||||
|
|
@ -580,6 +632,36 @@ config DRM_PANEL_SONY_ACX565AKM
|
|||
Say Y here if you want to enable support for the Sony ACX565AKM
|
||||
800x600 3.5" panel (found on the Nokia N900).
|
||||
|
||||
config DRM_PANEL_SONY_DISCOVERY_TD4322_INNOLUX
|
||||
tristate "Sony Discovery TD4322 Innolux panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
Say Y here if you want to enable the Innolux TD4322
|
||||
1080-1920 command mode panel (as found on Sony Xperia
|
||||
XA2 Ultra devices).
|
||||
|
||||
config DRM_PANEL_SONY_PIONEER_TD4322_TRULY
|
||||
tristate "Sony Pioneer TD4322 Truly panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
Say Y here if you want to enable the Truly TD4322 1080x
|
||||
1920 command mode display panel (as found on Sony Xperia XA2
|
||||
devices).
|
||||
|
||||
config DRM_PANEL_SONY_VOYAGER_TD4328_TIANMA
|
||||
tristate "Sony Voyager TD4328 Tianma panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
Say Y here if you want to enable the Tianma TD4328 1080x
|
||||
2160 command mode panel (as found on Sony Xperia XA2 Plus
|
||||
devices).
|
||||
|
||||
config DRM_PANEL_TDO_TL070WSH30
|
||||
tristate "TDO TL070WSH30 DSI panel"
|
||||
depends on OF
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
obj-$(CONFIG_DRM_PANEL_ABT_Y030XX067A) += panel-abt-y030xx067a.o
|
||||
obj-$(CONFIG_DRM_PANEL_ARM_VERSATILE) += panel-arm-versatile.o
|
||||
obj-$(CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596) += panel-asus-z00t-tm5p5-n35596.o
|
||||
obj-$(CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0) += panel-boe-bf060y8m-aj0.o
|
||||
obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o
|
||||
obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o
|
||||
obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o
|
||||
|
|
@ -25,6 +26,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
|
|||
obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
|
||||
obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
|
||||
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
|
||||
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
|
||||
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o
|
||||
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
|
||||
obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o
|
||||
|
|
@ -41,6 +43,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
|
||||
|
|
@ -59,6 +63,9 @@ obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o
|
|||
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
|
||||
obj-$(CONFIG_DRM_PANEL_SONY_ACX424AKP) += panel-sony-acx424akp.o
|
||||
obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
|
||||
obj-$(CONFIG_DRM_PANEL_SONY_DISCOVERY_TD4322_INNOLUX) += panel-td4322-innolux-fhd.o
|
||||
obj-$(CONFIG_DRM_PANEL_SONY_PIONEER_TD4322_TRULY) += panel-td4322-truly-fhd.o
|
||||
obj-$(CONFIG_DRM_PANEL_SONY_VOYAGER_TD4328_TIANMA) += panel-td4328-tianma-fhdplus.o
|
||||
obj-$(CONFIG_DRM_PANEL_TDO_TL070WSH30) += panel-tdo-tl070wsh30.o
|
||||
obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
|
||||
obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
|
||||
|
|
|
|||
445
drivers/gpu/drm/panel/panel-boe-bf060y8m-aj0.c
Normal file
445
drivers/gpu/drm/panel/panel-boe-bf060y8m-aj0.c
Normal file
|
|
@ -0,0 +1,445 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* BOE BF060Y8M-AJ0 5.99" MIPI-DSI OLED Panel on SW43404 DriverIC
|
||||
*
|
||||
* Copyright (c) 2020 AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
*/
|
||||
|
||||
#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_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
#define DCS_ALLOW_HBM_RANGE 0x0c
|
||||
#define DCS_DISALLOW_HBM_RANGE 0x08
|
||||
|
||||
enum boe_bf060y8m_aj0_supplies {
|
||||
BF060Y8M_VREG_VCC,
|
||||
BF060Y8M_VREG_VDDIO,
|
||||
BF060Y8M_VREG_VCI,
|
||||
BF060Y8M_VREG_EL_VDD,
|
||||
BF060Y8M_VREG_EL_VSS,
|
||||
BF060Y8M_VREG_MAX
|
||||
};
|
||||
|
||||
struct boe_bf060y8m_aj0 {
|
||||
struct drm_panel panel;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator_bulk_data vregs[BF060Y8M_VREG_MAX];
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline
|
||||
struct boe_bf060y8m_aj0 *to_boe_bf060y8m_aj0(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct boe_bf060y8m_aj0, 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 boe_bf060y8m_aj0_reset(struct boe_bf060y8m_aj0 *boe)
|
||||
{
|
||||
gpiod_set_value_cansleep(boe->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(boe->reset_gpio, 1);
|
||||
usleep_range(15000, 16000);
|
||||
gpiod_set_value_cansleep(boe->reset_gpio, 0);
|
||||
usleep_range(5000, 6000);
|
||||
}
|
||||
|
||||
static int boe_bf060y8m_aj0_on(struct boe_bf060y8m_aj0 *boe)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = boe->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi_dcs_write_seq(dsi, 0xb0, 0xa5, 0x00);
|
||||
dsi_dcs_write_seq(dsi, 0xb2, 0x00, 0x4c);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_SET_3D_CONTROL, 0x10);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, DCS_ALLOW_HBM_RANGE);
|
||||
dsi_dcs_write_seq(dsi, 0xf8,
|
||||
0x00, 0x08, 0x10, 0x00, 0x22, 0x00, 0x00, 0x2d);
|
||||
|
||||
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(30);
|
||||
|
||||
dsi_dcs_write_seq(dsi, 0xb0, 0xa5, 0x00);
|
||||
dsi_dcs_write_seq(dsi, 0xc0,
|
||||
0x08, 0x48, 0x65, 0x33, 0x33, 0x33,
|
||||
0x2a, 0x31, 0x39, 0x20, 0x09);
|
||||
dsi_dcs_write_seq(dsi, 0xc1, 0x00, 0x00, 0x00, 0x1f, 0x1f,
|
||||
0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
|
||||
0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f);
|
||||
dsi_dcs_write_seq(dsi, 0xe2, 0x20, 0x04, 0x10, 0x12, 0x92,
|
||||
0x4f, 0x8f, 0x44, 0x84, 0x83, 0x83, 0x83,
|
||||
0x5c, 0x5c, 0x5c);
|
||||
dsi_dcs_write_seq(dsi, 0xde, 0x01, 0x2c, 0x00, 0x77, 0x3e);
|
||||
|
||||
msleep(30);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(50);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int boe_bf060y8m_aj0_off(struct boe_bf060y8m_aj0 *boe)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = boe->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
/* OFF commands sent in HS mode */
|
||||
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(20);
|
||||
|
||||
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
usleep_range(1000, 2000);
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int boe_bf060y8m_aj0_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct boe_bf060y8m_aj0 *boe = to_boe_bf060y8m_aj0(panel);
|
||||
struct device *dev = &boe->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (boe->prepared)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Enable EL Driving Voltage first - doing that at the beginning
|
||||
* or at the end of the power sequence doesn't matter, so enable
|
||||
* it here to avoid yet another usleep at the end.
|
||||
*/
|
||||
ret = regulator_enable(boe->vregs[BF060Y8M_VREG_EL_VDD].consumer);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = regulator_enable(boe->vregs[BF060Y8M_VREG_EL_VSS].consumer);
|
||||
if (ret)
|
||||
goto err_elvss;
|
||||
|
||||
ret = regulator_enable(boe->vregs[BF060Y8M_VREG_VCC].consumer);
|
||||
if (ret)
|
||||
goto err_vcc;
|
||||
usleep_range(1000, 2000);
|
||||
ret = regulator_enable(boe->vregs[BF060Y8M_VREG_VDDIO].consumer);
|
||||
if (ret)
|
||||
goto err_vddio;
|
||||
usleep_range(500, 1000);
|
||||
ret = regulator_enable(boe->vregs[BF060Y8M_VREG_VCI].consumer);
|
||||
if (ret)
|
||||
goto err_vci;
|
||||
usleep_range(2000, 3000);
|
||||
|
||||
boe_bf060y8m_aj0_reset(boe);
|
||||
|
||||
ret = boe_bf060y8m_aj0_on(boe);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
gpiod_set_value_cansleep(boe->reset_gpio, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
boe->prepared = true;
|
||||
return 0;
|
||||
|
||||
err_vci:
|
||||
regulator_disable(boe->vregs[BF060Y8M_VREG_VDDIO].consumer);
|
||||
err_vddio:
|
||||
regulator_disable(boe->vregs[BF060Y8M_VREG_VCC].consumer);
|
||||
err_vcc:
|
||||
regulator_disable(boe->vregs[BF060Y8M_VREG_EL_VSS].consumer);
|
||||
err_elvss:
|
||||
regulator_disable(boe->vregs[BF060Y8M_VREG_EL_VDD].consumer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int boe_bf060y8m_aj0_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct boe_bf060y8m_aj0 *boe = to_boe_bf060y8m_aj0(panel);
|
||||
struct device *dev = &boe->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!boe->prepared)
|
||||
return 0;
|
||||
|
||||
ret = boe_bf060y8m_aj0_off(boe);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(boe->reset_gpio, 1);
|
||||
ret = regulator_bulk_disable(ARRAY_SIZE(boe->vregs), boe->vregs);
|
||||
|
||||
boe->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode boe_bf060y8m_aj0_mode = {
|
||||
.clock = 165268,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 36,
|
||||
.hsync_end = 1080 + 36 + 24,
|
||||
.htotal = 1080 + 36 + 24 + 96,
|
||||
.vdisplay = 2160,
|
||||
.vsync_start = 2160 + 16,
|
||||
.vsync_end = 2160 + 16 + 1,
|
||||
.vtotal = 2160 + 16 + 1 + 15,
|
||||
.width_mm = 68, /* 68.04 mm */
|
||||
.height_mm = 136, /* 136.08 mm */
|
||||
};
|
||||
|
||||
static int boe_bf060y8m_aj0_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &boe_bf060y8m_aj0_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 boe_bf060y8m_aj0_panel_funcs = {
|
||||
.prepare = boe_bf060y8m_aj0_prepare,
|
||||
.unprepare = boe_bf060y8m_aj0_unprepare,
|
||||
.get_modes = boe_bf060y8m_aj0_get_modes,
|
||||
};
|
||||
|
||||
static int boe_bf060y8m_aj0_bl_update_status(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness = backlight_get_brightness(bl);
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int boe_bf060y8m_aj0_bl_get_brightness(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness;
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return brightness & 0xff;
|
||||
}
|
||||
|
||||
static const struct backlight_ops boe_bf060y8m_aj0_bl_ops = {
|
||||
.update_status = boe_bf060y8m_aj0_bl_update_status,
|
||||
.get_brightness = boe_bf060y8m_aj0_bl_get_brightness,
|
||||
};
|
||||
|
||||
static struct backlight_device *
|
||||
boe_bf060y8m_aj0_create_backlight(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
const struct backlight_properties props = {
|
||||
.type = BACKLIGHT_RAW,
|
||||
.brightness = 127,
|
||||
.max_brightness = 255,
|
||||
.scale = BACKLIGHT_SCALE_NON_LINEAR,
|
||||
};
|
||||
|
||||
return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
|
||||
&boe_bf060y8m_aj0_bl_ops, &props);
|
||||
}
|
||||
|
||||
static int boe_bf060y8m_aj0_init_vregs(struct boe_bf060y8m_aj0 *boe,
|
||||
struct device *dev)
|
||||
{
|
||||
struct regulator *vreg;
|
||||
int ret;
|
||||
|
||||
boe->vregs[BF060Y8M_VREG_VCC].supply = "vcc";
|
||||
boe->vregs[BF060Y8M_VREG_VDDIO].supply = "vddio";
|
||||
boe->vregs[BF060Y8M_VREG_VCI].supply = "vci";
|
||||
boe->vregs[BF060Y8M_VREG_EL_VDD].supply = "elvdd";
|
||||
boe->vregs[BF060Y8M_VREG_EL_VSS].supply = "elvss";
|
||||
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(boe->vregs),
|
||||
boe->vregs);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to get regulators: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vreg = boe->vregs[BF060Y8M_VREG_VCC].consumer;
|
||||
ret = regulator_is_supported_voltage(vreg, 2700000, 3600000);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
vreg = boe->vregs[BF060Y8M_VREG_VDDIO].consumer;
|
||||
ret = regulator_is_supported_voltage(vreg, 1620000, 1980000);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
vreg = boe->vregs[BF060Y8M_VREG_VCI].consumer;
|
||||
ret = regulator_is_supported_voltage(vreg, 2600000, 3600000);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
vreg = boe->vregs[BF060Y8M_VREG_EL_VDD].consumer;
|
||||
ret = regulator_is_supported_voltage(vreg, 4400000, 4800000);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
/* ELVSS is negative: -5.00V to -1.40V */
|
||||
vreg = boe->vregs[BF060Y8M_VREG_EL_VSS].consumer;
|
||||
ret = regulator_is_supported_voltage(vreg, 1400000, 5000000);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Set min/max rated current, known only for VCI and VDDIO and,
|
||||
* in case of failure, just go on gracefully, as this step is not
|
||||
* guaranteed to succeed on all regulator HW but do a debug print
|
||||
* to inform the developer during debugging.
|
||||
* In any case, these two supplies are also optional, so they may
|
||||
* be fixed-regulator which, at the time of writing, does not
|
||||
* support fake current limiting.
|
||||
*/
|
||||
vreg = boe->vregs[BF060Y8M_VREG_VDDIO].consumer;
|
||||
ret = regulator_set_current_limit(vreg, 1500, 2500);
|
||||
if (ret)
|
||||
dev_dbg(dev, "Current limit cannot be set on %s: %d\n",
|
||||
boe->vregs[1].supply, ret);
|
||||
|
||||
vreg = boe->vregs[BF060Y8M_VREG_VCI].consumer;
|
||||
ret = regulator_set_current_limit(vreg, 20000, 40000);
|
||||
if (ret)
|
||||
dev_dbg(dev, "Current limit cannot be set on %s: %d\n",
|
||||
boe->vregs[2].supply, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int boe_bf060y8m_aj0_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct boe_bf060y8m_aj0 *boe;
|
||||
int ret;
|
||||
|
||||
boe = devm_kzalloc(dev, sizeof(*boe), GFP_KERNEL);
|
||||
if (!boe)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = boe_bf060y8m_aj0_init_vregs(boe, dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to initialize supplies.\n");
|
||||
|
||||
boe->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
|
||||
if (IS_ERR(boe->reset_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(boe->reset_gpio),
|
||||
"Failed to get reset-gpios\n");
|
||||
|
||||
boe->dsi = dsi;
|
||||
mipi_dsi_set_drvdata(dsi, boe);
|
||||
|
||||
dsi->lanes = 4;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_EOT_PACKET |
|
||||
MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS |
|
||||
MIPI_DSI_MODE_LPM;
|
||||
|
||||
drm_panel_init(&boe->panel, dev, &boe_bf060y8m_aj0_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
boe->panel.backlight = boe_bf060y8m_aj0_create_backlight(dsi);
|
||||
if (IS_ERR(boe->panel.backlight))
|
||||
return dev_err_probe(dev, PTR_ERR(boe->panel.backlight),
|
||||
"Failed to create backlight\n");
|
||||
|
||||
drm_panel_add(&boe->panel);
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int boe_bf060y8m_aj0_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct boe_bf060y8m_aj0 *boe = 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(&boe->panel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id boe_bf060y8m_aj0_of_match[] = {
|
||||
{ .compatible = "boe,bf060y8m-aj0" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, boe_bf060y8m_aj0_of_match);
|
||||
|
||||
static struct mipi_dsi_driver boe_bf060y8m_aj0_driver = {
|
||||
.probe = boe_bf060y8m_aj0_probe,
|
||||
.remove = boe_bf060y8m_aj0_remove,
|
||||
.driver = {
|
||||
.name = "panel-sw43404-boe-fhd-amoled",
|
||||
.of_match_table = boe_bf060y8m_aj0_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(boe_bf060y8m_aj0_driver);
|
||||
|
||||
MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
|
||||
MODULE_DESCRIPTION("BOE BF060Y8M-AJ0 MIPI-DSI OLED panel");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
704
drivers/gpu/drm/panel/panel-novatek-nt35950.c
Normal file
704
drivers/gpu/drm/panel/panel-novatek-nt35950.c
Normal file
|
|
@ -0,0 +1,704 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Novatek NT35950 DriverIC panels driver
|
||||
*
|
||||
* Copyright (c) 2021 AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
#define MCS_CMD_MAUCCTR 0xf0 /* Manufacturer command enable */
|
||||
#define MCS_PARAM_SCALER_FUNCTION 0x58 /* Scale-up function */
|
||||
#define MCS_PARAM_SCALEUP_MODE 0xc9
|
||||
#define MCS_SCALEUP_SIMPLE 0x0
|
||||
#define MCS_SCALEUP_BILINEAR BIT(0)
|
||||
#define MCS_SCALEUP_DUPLICATE BIT(0) | BIT(4)
|
||||
|
||||
/* VESA Display Stream Compression param */
|
||||
#define MCS_PARAM_VESA_DSC_ON 0x03
|
||||
|
||||
/* Data Compression mode */
|
||||
#define MCS_PARAM_DATA_COMPRESSION 0x90
|
||||
#define MCS_DATA_COMPRESSION_NONE 0x00
|
||||
#define MCS_DATA_COMPRESSION_FBC 0x02
|
||||
#define MCS_DATA_COMPRESSION_DSC 0x03
|
||||
|
||||
/* Display Output control */
|
||||
#define MCS_PARAM_DISP_OUTPUT_CTRL 0xb4
|
||||
#define MCS_DISP_OUT_SRAM_EN BIT(0)
|
||||
#define MCS_DISP_OUT_VIDEO_MODE BIT(4)
|
||||
|
||||
/* VESA Display Stream Compression setting */
|
||||
#define MCS_PARAM_VESA_DSC_SETTING 0xc0
|
||||
|
||||
/* SubPixel Rendering (SPR) */
|
||||
#define MCS_PARAM_SPR_EN 0xe3
|
||||
#define MCS_PARAM_SPR_MODE 0xef
|
||||
#define MCS_SPR_MODE_YYG_RAINBOW_RGB 0x01
|
||||
|
||||
#define NT35950_VREG_MAX 4
|
||||
|
||||
struct nt35950 {
|
||||
struct drm_panel panel;
|
||||
struct drm_connector *connector;
|
||||
struct mipi_dsi_device *dsi[2];
|
||||
struct regulator_bulk_data vregs[NT35950_VREG_MAX];
|
||||
struct gpio_desc *reset_gpio;
|
||||
const struct nt35950_panel_desc *desc;
|
||||
|
||||
int cur_mode;
|
||||
u8 last_page;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
struct nt35950_panel_mode {
|
||||
const struct drm_display_mode mode;
|
||||
|
||||
bool enable_sram;
|
||||
bool is_video_mode;
|
||||
u8 scaler_on;
|
||||
u8 scaler_mode;
|
||||
u8 compression;
|
||||
u8 spr_en;
|
||||
u8 spr_mode;
|
||||
};
|
||||
|
||||
struct nt35950_panel_desc {
|
||||
const char* model_name;
|
||||
const struct mipi_dsi_device_info dsi_info;
|
||||
const struct nt35950_panel_mode *mode_data;
|
||||
|
||||
bool is_dual_dsi;
|
||||
u8 num_lanes;
|
||||
u8 num_modes;
|
||||
};
|
||||
|
||||
static inline struct nt35950 *to_nt35950(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct nt35950, 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 nt35950_reset(struct nt35950 *nt)
|
||||
{
|
||||
gpiod_set_value_cansleep(nt->reset_gpio, 1);
|
||||
usleep_range(12000, 13000);
|
||||
gpiod_set_value_cansleep(nt->reset_gpio, 0);
|
||||
usleep_range(300, 400);
|
||||
gpiod_set_value_cansleep(nt->reset_gpio, 1);
|
||||
usleep_range(12000, 13000);
|
||||
}
|
||||
|
||||
/*
|
||||
* nt35950_set_cmd2_page - Select manufacturer control (CMD2) page
|
||||
* @nt: Main driver structure
|
||||
* @page: Page number (0-7)
|
||||
*
|
||||
* Return: Number of transferred bytes or negative number on error
|
||||
*/
|
||||
static int nt35950_set_cmd2_page(struct nt35950 *nt, u8 page)
|
||||
{
|
||||
const u8 mauc_cmd2_page[] = { MCS_CMD_MAUCCTR, 0x55, 0xaa, 0x52,
|
||||
0x08, page };
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], mauc_cmd2_page,
|
||||
ARRAY_SIZE(mauc_cmd2_page));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
nt->last_page = page;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* nt35950_set_data_compression - Set data compression mode
|
||||
* @nt: Main driver structure
|
||||
* @comp_mode: Compression mode
|
||||
*
|
||||
* Return: Number of transferred bytes or negative number on error
|
||||
*/
|
||||
static int nt35950_set_data_compression(struct nt35950 *nt, u8 comp_mode)
|
||||
{
|
||||
u8 cmd_data_compression[] = { MCS_PARAM_DATA_COMPRESSION, comp_mode };
|
||||
u8 cmd_vesa_dsc_on[] = { MCS_PARAM_VESA_DSC_ON, !!comp_mode };
|
||||
u8 cmd_vesa_dsc_setting[] = { MCS_PARAM_VESA_DSC_SETTING, 0x03 };
|
||||
u8 last_page = nt->last_page;
|
||||
int ret;
|
||||
|
||||
/* Set CMD2 Page 0 if we're not there yet */
|
||||
if (last_page != 0) {
|
||||
ret = nt35950_set_cmd2_page(nt, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_data_compression,
|
||||
ARRAY_SIZE(cmd_data_compression));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_vesa_dsc_on,
|
||||
ARRAY_SIZE(cmd_vesa_dsc_on));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Set the vesa dsc setting on Page 4 */
|
||||
ret = nt35950_set_cmd2_page(nt, 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Display Stream Compression setting, always 0x03 */
|
||||
ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_vesa_dsc_setting,
|
||||
ARRAY_SIZE(cmd_vesa_dsc_setting));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Get back to the previously set page */
|
||||
return nt35950_set_cmd2_page(nt, last_page);
|
||||
}
|
||||
|
||||
/*
|
||||
* nt35950_set_scaler - Enable/disable resolution upscaling
|
||||
* @nt: Main driver structure
|
||||
* @scale_up: Scale up function control
|
||||
*
|
||||
* Return: Number of transferred bytes or negative number on error
|
||||
*/
|
||||
static int nt35950_set_scaler(struct nt35950 *nt, u8 scale_up)
|
||||
{
|
||||
u8 cmd_scaler[] = { MCS_PARAM_SCALER_FUNCTION, scale_up };
|
||||
|
||||
return mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_scaler,
|
||||
ARRAY_SIZE(cmd_scaler));
|
||||
}
|
||||
|
||||
/*
|
||||
* nt35950_set_scale_mode - Resolution upscaling mode
|
||||
* @nt: Main driver structure
|
||||
* @mode: Scaler mode
|
||||
*
|
||||
* Return: Number of transferred bytes or negative number on error
|
||||
*/
|
||||
static int nt35950_set_scale_mode(struct nt35950 *nt, u8 mode)
|
||||
{
|
||||
u8 cmd_scaler[] = { MCS_PARAM_SCALEUP_MODE, mode };
|
||||
|
||||
return mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_scaler,
|
||||
ARRAY_SIZE(cmd_scaler));
|
||||
}
|
||||
|
||||
/*
|
||||
* nt35950_inject_black_image - Display a completely black image
|
||||
* @nt: Main driver structure
|
||||
*
|
||||
* After IC setup, the attached panel may show random data
|
||||
* due to driveric behavior changes (resolution, compression,
|
||||
* scaling, etc). This function, called after parameters setup,
|
||||
* makes the driver ic to output a completely black image to
|
||||
* the display.
|
||||
* It makes sense to push a black image before sending the sleep-out
|
||||
* and display-on commands.
|
||||
*
|
||||
* Return: Number of transferred bytes or negative number on error
|
||||
*/
|
||||
static int nt35950_inject_black_image(struct nt35950 *nt)
|
||||
{
|
||||
const u8 cmd0_black_img[] = { 0x6f, 0x01 };
|
||||
const u8 cmd1_black_img[] = { 0xf3, 0x10 };
|
||||
u8 cmd_test[] = { 0xff, 0xaa, 0x55, 0xa5, 0x80 };
|
||||
int ret;
|
||||
|
||||
/* Enable test command */
|
||||
ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_test, ARRAY_SIZE(cmd_test));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Send a black image */
|
||||
ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd0_black_img,
|
||||
ARRAY_SIZE(cmd0_black_img));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd1_black_img,
|
||||
ARRAY_SIZE(cmd1_black_img));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Disable test command */
|
||||
cmd_test[ARRAY_SIZE(cmd_test) - 1] = 0x00;
|
||||
return mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_test, ARRAY_SIZE(cmd_test));
|
||||
}
|
||||
|
||||
/*
|
||||
* nt35950_set_dispout - Set Display Output register parameters
|
||||
* @nt: Main driver structure
|
||||
*
|
||||
* Return: Number of transferred bytes or negative number on error
|
||||
*/
|
||||
static int nt35950_set_dispout(struct nt35950 *nt)
|
||||
{
|
||||
u8 cmd_dispout[] = { MCS_PARAM_DISP_OUTPUT_CTRL, 0x00 };
|
||||
const struct nt35950_panel_mode *mode_data = nt->desc->mode_data;
|
||||
|
||||
if (mode_data[nt->cur_mode].is_video_mode)
|
||||
cmd_dispout[1] |= MCS_DISP_OUT_VIDEO_MODE;
|
||||
if (mode_data[nt->cur_mode].enable_sram)
|
||||
cmd_dispout[1] |= MCS_DISP_OUT_SRAM_EN;
|
||||
|
||||
return mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_dispout,
|
||||
ARRAY_SIZE(cmd_dispout));
|
||||
}
|
||||
|
||||
static int nt35950_get_current_mode(struct nt35950 *nt)
|
||||
{
|
||||
struct drm_connector *connector = nt->connector;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
int i;
|
||||
|
||||
/* Return the default (first) mode if no info available yet */
|
||||
if (!connector->state || !connector->state->crtc)
|
||||
return 0;
|
||||
|
||||
crtc_state = connector->state->crtc->state;
|
||||
|
||||
for (i = 0; i < nt->desc->num_modes; i++) {
|
||||
if (drm_mode_match(&crtc_state->mode,
|
||||
&nt->desc->mode_data[i].mode,
|
||||
DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_CLOCK))
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nt35950_on(struct nt35950 *nt)
|
||||
{
|
||||
const struct nt35950_panel_mode *mode_data = nt->desc->mode_data;
|
||||
struct mipi_dsi_device *dsi = nt->dsi[0];
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
nt->cur_mode = nt35950_get_current_mode(nt);
|
||||
nt->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
nt->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = nt35950_set_cmd2_page(nt, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nt35950_set_data_compression(nt, mode_data[nt->cur_mode].compression);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nt35950_set_scale_mode(nt, mode_data[nt->cur_mode].scaler_mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nt35950_set_scaler(nt, mode_data[nt->cur_mode].scaler_on);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nt35950_set_dispout(nt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set tear scanline: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* CMD2 Page 1 */
|
||||
ret = nt35950_set_cmd2_page(nt, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Unknown command */
|
||||
dsi_dcs_write_seq(dsi, 0xd4, 0x88, 0x88);
|
||||
|
||||
/* CMD2 Page 7 */
|
||||
ret = nt35950_set_cmd2_page(nt, 7);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Enable SubPixel Rendering */
|
||||
dsi_dcs_write_seq(dsi, MCS_PARAM_SPR_EN, 0x01);
|
||||
|
||||
/* SPR Mode: YYG Rainbow-RGB */
|
||||
dsi_dcs_write_seq(dsi, MCS_PARAM_SPR_MODE, MCS_SPR_MODE_YYG_RAINBOW_RGB);
|
||||
|
||||
/* CMD3 */
|
||||
ret = nt35950_inject_black_image(nt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
msleep(120);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
msleep(120);
|
||||
|
||||
nt->dsi[0]->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
nt->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nt35950_off(struct nt35950 *nt)
|
||||
{
|
||||
struct device *dev = &nt->dsi[0]->dev;
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_off(nt->dsi[0]);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display off: %d\n", ret);
|
||||
goto set_lpm;
|
||||
}
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
ret = mipi_dsi_dcs_enter_sleep_mode(nt->dsi[0]);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
|
||||
goto set_lpm;
|
||||
}
|
||||
msleep(150);
|
||||
|
||||
set_lpm:
|
||||
nt->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
nt->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nt35950_sharp_init_vregs(struct nt35950 *nt, struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
nt->vregs[0].supply = "vddio";
|
||||
nt->vregs[1].supply = "avdd";
|
||||
nt->vregs[2].supply = "avee";
|
||||
nt->vregs[3].supply = "dvdd";
|
||||
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(nt->vregs),
|
||||
nt->vregs);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regulator_is_supported_voltage(nt->vregs[0].consumer,
|
||||
1750000, 1950000);
|
||||
if (!ret)
|
||||
return -EINVAL;
|
||||
ret = regulator_is_supported_voltage(nt->vregs[1].consumer,
|
||||
5200000, 5900000);
|
||||
if (!ret)
|
||||
return -EINVAL;
|
||||
/* AVEE is negative: -5.90V to -5.20V */
|
||||
ret = regulator_is_supported_voltage(nt->vregs[2].consumer,
|
||||
5200000, 5900000);
|
||||
if (!ret)
|
||||
return -EINVAL;
|
||||
|
||||
ret = regulator_is_supported_voltage(nt->vregs[3].consumer,
|
||||
1300000, 1400000);
|
||||
if (!ret)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nt35950_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct nt35950 *nt = to_nt35950(panel);
|
||||
struct device *dev = &nt->dsi[0]->dev;
|
||||
int ret;
|
||||
|
||||
if (nt->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_enable(nt->vregs[0].consumer);
|
||||
if (ret)
|
||||
return ret;
|
||||
usleep_range(2000, 5000);
|
||||
|
||||
ret = regulator_enable(nt->vregs[3].consumer);
|
||||
if (ret)
|
||||
goto end;
|
||||
usleep_range(15000, 18000);
|
||||
|
||||
ret = regulator_enable(nt->vregs[1].consumer);
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
ret = regulator_enable(nt->vregs[2].consumer);
|
||||
if (ret)
|
||||
goto end;
|
||||
usleep_range(12000, 13000);
|
||||
|
||||
nt35950_reset(nt);
|
||||
|
||||
ret = nt35950_on(nt);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
goto end;
|
||||
}
|
||||
nt->prepared = true;
|
||||
|
||||
end:
|
||||
if (ret < 0) {
|
||||
regulator_bulk_disable(ARRAY_SIZE(nt->vregs), nt->vregs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nt35950_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct nt35950 *nt = to_nt35950(panel);
|
||||
struct device *dev = &nt->dsi[0]->dev;
|
||||
int ret;
|
||||
|
||||
if (!nt->prepared)
|
||||
return 0;
|
||||
|
||||
ret = nt35950_off(nt);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to deinitialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(nt->reset_gpio, 0);
|
||||
regulator_bulk_disable(ARRAY_SIZE(nt->vregs), nt->vregs);
|
||||
|
||||
nt->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nt35950_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct nt35950 *nt = to_nt35950(panel);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nt->desc->num_modes; i++) {
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev,
|
||||
&nt->desc->mode_data[i].mode);
|
||||
if (!mode)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type |= DRM_MODE_TYPE_DRIVER;
|
||||
if (nt->desc->num_modes == 1)
|
||||
mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||
|
||||
drm_mode_probed_add(connector, mode);
|
||||
}
|
||||
|
||||
connector->display_info.bpc = 8;
|
||||
connector->display_info.height_mm = nt->desc->mode_data[0].mode.height_mm;
|
||||
connector->display_info.width_mm = nt->desc->mode_data[0].mode.width_mm;
|
||||
nt->connector = connector;
|
||||
|
||||
return nt->desc->num_modes;
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs nt35950_panel_funcs = {
|
||||
.prepare = nt35950_prepare,
|
||||
.unprepare = nt35950_unprepare,
|
||||
.get_modes = nt35950_get_modes,
|
||||
};
|
||||
|
||||
static int nt35950_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct device_node *dsi_r;
|
||||
struct mipi_dsi_host *dsi_r_host;
|
||||
struct nt35950 *nt;
|
||||
const struct mipi_dsi_device_info *info;
|
||||
int i, num_dsis = 1, ret;
|
||||
|
||||
nt = devm_kzalloc(dev, sizeof(*nt), GFP_KERNEL);
|
||||
if (!nt)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = nt35950_sharp_init_vregs(nt, dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Regulator init failure.\n");
|
||||
|
||||
nt->desc = of_device_get_match_data(dev);
|
||||
if (!nt->desc)
|
||||
return -ENODEV;
|
||||
|
||||
nt->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
|
||||
if (IS_ERR(nt->reset_gpio)) {
|
||||
return dev_err_probe(dev, PTR_ERR(nt->reset_gpio),
|
||||
"Failed to get reset gpio\n");
|
||||
}
|
||||
|
||||
/* If the panel is connected on two DSIs then DSI0 left, DSI1 right */
|
||||
if (nt->desc->is_dual_dsi) {
|
||||
info = &nt->desc->dsi_info;
|
||||
dsi_r = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
|
||||
if (!dsi_r) {
|
||||
dev_err(dev, "Cannot get secondary DSI node.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
dsi_r_host = of_find_mipi_dsi_host_by_node(dsi_r);
|
||||
of_node_put(dsi_r);
|
||||
if (!dsi_r_host) {
|
||||
dev_err(dev, "Cannot get secondary DSI host\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info);
|
||||
if (!nt->dsi[1]) {
|
||||
dev_err(dev, "Cannot get secondary DSI node\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
num_dsis++;
|
||||
}
|
||||
|
||||
nt->dsi[0] = dsi;
|
||||
mipi_dsi_set_drvdata(dsi, nt);
|
||||
|
||||
drm_panel_init(&nt->panel, dev, &nt35950_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_of_backlight(&nt->panel);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to get backlight\n");
|
||||
|
||||
drm_panel_add(&nt->panel);
|
||||
|
||||
for (i = 0; i < num_dsis; i++) {
|
||||
nt->dsi[i]->lanes = nt->desc->num_lanes;
|
||||
nt->dsi[i]->format = MIPI_DSI_FMT_RGB888;
|
||||
|
||||
nt->dsi[i]->mode_flags = MIPI_DSI_MODE_EOT_PACKET |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS |
|
||||
MIPI_DSI_MODE_LPM;
|
||||
|
||||
if (nt->desc->mode_data[0].is_video_mode)
|
||||
nt->dsi[i]->mode_flags |= MIPI_DSI_MODE_VIDEO;
|
||||
|
||||
ret = mipi_dsi_attach(nt->dsi[i]);
|
||||
if (ret < 0) {
|
||||
return dev_err_probe(dev, ret,
|
||||
"Cannot attach to DSI%d host.\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure to set RESX LOW before starting the power-on sequence */
|
||||
gpiod_set_value_cansleep(nt->reset_gpio, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nt35950_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct nt35950 *nt = mipi_dsi_get_drvdata(dsi);
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_detach(nt->dsi[0]);
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev,
|
||||
"Failed to detach from DSI0 host: %d\n", ret);
|
||||
|
||||
if (nt->dsi[1]) {
|
||||
ret = mipi_dsi_detach(nt->dsi[1]);
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev,
|
||||
"Failed to detach from DSI1 host: %d\n", ret);
|
||||
mipi_dsi_device_unregister(nt->dsi[1]);
|
||||
};
|
||||
|
||||
drm_panel_remove(&nt->panel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nt35950_panel_mode sharp_ls055d1sx04_modes[] = {
|
||||
{
|
||||
/* 1920x1080 60Hz no compression */
|
||||
.mode = {
|
||||
.clock = 214537,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 400,
|
||||
.hsync_end = 1080 + 400 + 40,
|
||||
.htotal = 1080 + 400 + 40 + 300,
|
||||
.vdisplay = 1920,
|
||||
.vsync_start = 1920 + 12,
|
||||
.vsync_end = 1920 + 12 + 2,
|
||||
.vtotal = 1920 + 12 + 2 + 10,
|
||||
.width_mm = 68,
|
||||
.height_mm = 121,
|
||||
.type = DRM_MODE_TYPE_PREFERRED,
|
||||
},
|
||||
.compression = MCS_DATA_COMPRESSION_NONE,
|
||||
.enable_sram = true,
|
||||
.is_video_mode = false,
|
||||
.scaler_on = 1,
|
||||
.scaler_mode = MCS_SCALEUP_DUPLICATE,
|
||||
},
|
||||
/* TODO: Add 2160x3840 60Hz when DSC is supported */
|
||||
};
|
||||
|
||||
const struct nt35950_panel_desc sharp_ls055d1sx04 = {
|
||||
.model_name = "Sharp LS055D1SX04",
|
||||
.dsi_info = {
|
||||
.type = "LS055D1SX04",
|
||||
.channel = 0,
|
||||
.node = NULL,
|
||||
},
|
||||
.mode_data = sharp_ls055d1sx04_modes,
|
||||
.num_modes = ARRAY_SIZE(sharp_ls055d1sx04_modes),
|
||||
.is_dual_dsi = true,
|
||||
.num_lanes = 4,
|
||||
};
|
||||
|
||||
static const struct of_device_id nt35950_of_match[] = {
|
||||
{ .compatible = "sharp,ls055d1sx04", .data = &sharp_ls055d1sx04 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, nt35950_of_match);
|
||||
|
||||
static struct mipi_dsi_driver nt35950_driver = {
|
||||
.probe = nt35950_probe,
|
||||
.remove = nt35950_remove,
|
||||
.driver = {
|
||||
.name = "panel-novatek-nt35950",
|
||||
.of_match_table = nt35950_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(nt35950_driver);
|
||||
|
||||
MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
|
||||
MODULE_DESCRIPTION("Novatek NT35950 DriverIC panels driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
351
drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c
Normal file
351
drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
// 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;
|
||||
drm_connector_set_panel_orientation(connector, ctx->orientation);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs s6e3fa5_panel_funcs = {
|
||||
.prepare = s6e3fa5_prepare,
|
||||
.unprepare = s6e3fa5_unprepare,
|
||||
.get_modes = s6e3fa5_get_modes,
|
||||
};
|
||||
|
||||
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 int 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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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");
|
||||
345
drivers/gpu/drm/panel/panel-samsung-s6e3fc1.c
Normal file
345
drivers/gpu/drm/panel/panel-samsung-s6e3fc1.c
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
// 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 int 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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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");
|
||||
|
|
@ -4187,6 +4187,68 @@ static const struct panel_desc_dsi osd101t2045_53ts = {
|
|||
.lanes = 4,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode sony_kirin_nt36672a_truly_mode = {
|
||||
.clock = (1080 + 25 + 12 + 120) * (2520 + 12 + 4 + 10) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 25,
|
||||
.hsync_end = 1080 + 25 + 12,
|
||||
.htotal = 1080 + 25 + 12 + 120,
|
||||
.vdisplay = 2520,
|
||||
.vsync_start = 2520 + 12,
|
||||
.vsync_end = 2520 + 12 + 4,
|
||||
.vtotal = 2520 + 12 + 4 + 10,
|
||||
.width_mm = 60,
|
||||
.height_mm = 139,
|
||||
};
|
||||
|
||||
static const struct panel_desc_dsi sony_kirin_nt36672a_truly = {
|
||||
.desc = {
|
||||
.modes = &sony_kirin_nt36672a_truly_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 60,
|
||||
.height = 139,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_DSI,
|
||||
},
|
||||
.flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS,
|
||||
.format = MIPI_DSI_FMT_RGB888,
|
||||
.lanes = 4,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode sony_mermaid_nt36672a_tianma_mode = {
|
||||
.clock = (1080 + 102 + 20 + 40) * (2520 + 10 + 2 + 8) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 102,
|
||||
.hsync_end = 1080 + 102 + 20,
|
||||
.htotal = 1080 + 102 + 20 + 40,
|
||||
.vdisplay = 2520,
|
||||
.vsync_start = 2520 + 10,
|
||||
.vsync_end = 2520 + 10 + 2,
|
||||
.vtotal = 2520 + 10 + 2 + 8,
|
||||
.width_mm = 65,
|
||||
.height_mm = 151,
|
||||
};
|
||||
|
||||
static const struct panel_desc_dsi sony_mermaid_nt36672a_tianma = {
|
||||
.desc = {
|
||||
.modes = &sony_mermaid_nt36672a_tianma_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 65,
|
||||
.height = 151,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_DSI,
|
||||
},
|
||||
.flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS,
|
||||
.format = MIPI_DSI_FMT_RGB888,
|
||||
.lanes = 4,
|
||||
};
|
||||
|
||||
static const struct of_device_id dsi_of_match[] = {
|
||||
{
|
||||
.compatible = "auo,b080uan01",
|
||||
|
|
@ -4209,6 +4271,12 @@ static const struct of_device_id dsi_of_match[] = {
|
|||
}, {
|
||||
.compatible = "osddisplays,osd101t2045-53ts",
|
||||
.data = &osd101t2045_53ts
|
||||
}, {
|
||||
.compatible = "sony,kirin-nt36672a-truly",
|
||||
.data = &sony_kirin_nt36672a_truly
|
||||
}, {
|
||||
.compatible = "sony,mermaid-nt36672a-tianma",
|
||||
.data = &sony_mermaid_nt36672a_tianma
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
|
|
|
|||
265
drivers/gpu/drm/panel/panel-td4322-innolux-fhd.c
Normal file
265
drivers/gpu/drm/panel/panel-td4322-innolux-fhd.c
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
struct td4322_innolux_fhd {
|
||||
struct drm_panel panel;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator_bulk_data supplies[4];
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline
|
||||
struct td4322_innolux_fhd *to_td4322_innolux_fhd(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct td4322_innolux_fhd, 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 td4322_innolux_fhd_reset(struct td4322_innolux_fhd *ctx)
|
||||
{
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
msleep(30);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
msleep(150);
|
||||
}
|
||||
|
||||
static int td4322_innolux_fhd_on(struct td4322_innolux_fhd *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_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;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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(70);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4322_innolux_fhd_off(struct td4322_innolux_fhd *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(20);
|
||||
|
||||
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(120);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4322_innolux_fhd_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct td4322_innolux_fhd *ctx = to_td4322_innolux_fhd(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulators: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
td4322_innolux_fhd_reset(ctx);
|
||||
|
||||
ret = td4322_innolux_fhd_on(ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->prepared = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4322_innolux_fhd_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct td4322_innolux_fhd *ctx = to_td4322_innolux_fhd(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = td4322_innolux_fhd_off(ctx);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
|
||||
ctx->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode td4322_innolux_fhd_mode = {
|
||||
.clock = (1080 + 96 + 20 + 48) * (1920 + 5 + 2 + 3) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 96,
|
||||
.hsync_end = 1080 + 96 + 20,
|
||||
.htotal = 1080 + 96 + 20 + 48,
|
||||
.vdisplay = 1920,
|
||||
.vsync_start = 1920 + 5,
|
||||
.vsync_end = 1920 + 5 + 2,
|
||||
.vtotal = 1920 + 5 + 2 + 3,
|
||||
.width_mm = 74,
|
||||
.height_mm = 132,
|
||||
};
|
||||
|
||||
static int td4322_innolux_fhd_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &td4322_innolux_fhd_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 td4322_innolux_fhd_panel_funcs = {
|
||||
.prepare = td4322_innolux_fhd_prepare,
|
||||
.unprepare = td4322_innolux_fhd_unprepare,
|
||||
.get_modes = td4322_innolux_fhd_get_modes,
|
||||
};
|
||||
|
||||
static int td4322_innolux_fhd_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct td4322_innolux_fhd *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->supplies[0].supply = "vdd";
|
||||
ctx->supplies[1].supply = "vddio";
|
||||
ctx->supplies[2].supply = "vsn";
|
||||
ctx->supplies[3].supply = "vsp";
|
||||
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
|
||||
ctx->supplies);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to get regulators\n");
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
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_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &td4322_innolux_fhd_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_of_backlight(&ctx->panel);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to get backlight\n");
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to attach to DSI host\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4322_innolux_fhd_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct td4322_innolux_fhd *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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id td4322_innolux_fhd_of_match[] = {
|
||||
{ .compatible = "sony,discovery-td4322-innolux" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, td4322_innolux_fhd_of_match);
|
||||
|
||||
static struct mipi_dsi_driver td4322_innolux_fhd_driver = {
|
||||
.probe = td4322_innolux_fhd_probe,
|
||||
.remove = td4322_innolux_fhd_remove,
|
||||
.driver = {
|
||||
.name = "panel-td4322-innolux-fhd",
|
||||
.of_match_table = td4322_innolux_fhd_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(td4322_innolux_fhd_driver);
|
||||
|
||||
MODULE_AUTHOR("Konrad Dybcio <konradybcio@gmail.com>");
|
||||
MODULE_DESCRIPTION("DRM driver for Sony TD4322 Innolux FHD panel");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
277
drivers/gpu/drm/panel/panel-td4322-truly-fhd.c
Normal file
277
drivers/gpu/drm/panel/panel-td4322-truly-fhd.c
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
struct td4322_truly_fhd {
|
||||
struct drm_panel panel;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator_bulk_data supplies[4];
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline
|
||||
struct td4322_truly_fhd *to_td4322_truly_fhd(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct td4322_truly_fhd, panel);
|
||||
}
|
||||
|
||||
#define dsi_generic_write_seq(dsi, seq...) do { \
|
||||
static const u8 d[] = { seq }; \
|
||||
int ret; \
|
||||
ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
static void td4322_truly_fhd_reset(struct td4322_truly_fhd *ctx)
|
||||
{
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
msleep(30);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
msleep(150);
|
||||
}
|
||||
|
||||
static int td4322_truly_fhd_on(struct td4322_truly_fhd *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
dsi_generic_write_seq(dsi, 0xb0, 0x00);
|
||||
dsi_generic_write_seq(dsi, 0xd5,
|
||||
0x03, 0x00, 0x00, 0x02, 0x23, 0x02, 0x23);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(30);
|
||||
|
||||
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(120);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4322_truly_fhd_off(struct td4322_truly_fhd *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(20);
|
||||
|
||||
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(120);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4322_truly_fhd_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct td4322_truly_fhd *ctx = to_td4322_truly_fhd(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulators: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
td4322_truly_fhd_reset(ctx);
|
||||
|
||||
ret = td4322_truly_fhd_on(ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->prepared = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4322_truly_fhd_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct td4322_truly_fhd *ctx = to_td4322_truly_fhd(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = td4322_truly_fhd_off(ctx);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
|
||||
ctx->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode td4322_truly_fhd_mode = {
|
||||
.clock = (1080 + 104 + 20 + 56) * (1920 + 10 + 2 + 8) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 104,
|
||||
.hsync_end = 1080 + 104 + 20,
|
||||
.htotal = 1080 + 104 + 20 + 56,
|
||||
.vdisplay = 1920,
|
||||
.vsync_start = 1920 + 10,
|
||||
.vsync_end = 1920 + 10 + 2,
|
||||
.vtotal = 1920 + 10 + 2 + 8,
|
||||
.width_mm = 64,
|
||||
.height_mm = 115,
|
||||
};
|
||||
|
||||
static int td4322_truly_fhd_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &td4322_truly_fhd_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 td4322_truly_fhd_panel_funcs = {
|
||||
.prepare = td4322_truly_fhd_prepare,
|
||||
.unprepare = td4322_truly_fhd_unprepare,
|
||||
.get_modes = td4322_truly_fhd_get_modes,
|
||||
};
|
||||
|
||||
static int td4322_truly_fhd_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct td4322_truly_fhd *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->supplies[0].supply = "vdd";
|
||||
ctx->supplies[1].supply = "vddio";
|
||||
ctx->supplies[2].supply = "vsn";
|
||||
ctx->supplies[3].supply = "vsp";
|
||||
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
|
||||
ctx->supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to get regulators: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ctx->reset_gpio)) {
|
||||
ret = PTR_ERR(ctx->reset_gpio);
|
||||
dev_err(dev, "Failed to get reset-gpios: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &td4322_truly_fhd_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_of_backlight(&ctx->panel);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get backlight: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to add panel: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4322_truly_fhd_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct td4322_truly_fhd *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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id td4322_truly_fhd_of_match[] = {
|
||||
{ .compatible = "sony,pioneer-td4322-truly" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, td4322_truly_fhd_of_match);
|
||||
|
||||
static struct mipi_dsi_driver td4322_truly_fhd_driver = {
|
||||
.probe = td4322_truly_fhd_probe,
|
||||
.remove = td4322_truly_fhd_remove,
|
||||
.driver = {
|
||||
.name = "panel-td4322-truly-fhd",
|
||||
.of_match_table = td4322_truly_fhd_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(td4322_truly_fhd_driver);
|
||||
|
||||
MODULE_AUTHOR("Konrad Dybcio <konradybcio@gmail.com>");
|
||||
MODULE_DESCRIPTION("DRM driver for TD4322 Truly FHD CMD mode panel");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
264
drivers/gpu/drm/panel/panel-td4328-tianma-fhdplus.c
Normal file
264
drivers/gpu/drm/panel/panel-td4328-tianma-fhdplus.c
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
struct td4328_tianma_fhdplus {
|
||||
struct drm_panel panel;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator_bulk_data supplies[4];
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline
|
||||
struct td4328_tianma_fhdplus *to_td4328_tianma_fhdplus(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct td4328_tianma_fhdplus, panel);
|
||||
}
|
||||
|
||||
#define dsi_generic_write_seq(dsi, seq...) do { \
|
||||
static const u8 d[] = { seq }; \
|
||||
int ret; \
|
||||
ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
static void td4328_tianma_fhdplus_reset(struct td4328_tianma_fhdplus *ctx)
|
||||
{
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
msleep(30);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
msleep(150);
|
||||
}
|
||||
|
||||
static int td4328_tianma_fhdplus_on(struct td4328_tianma_fhdplus *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
dsi_generic_write_seq(dsi, 0xb0, 0x04);
|
||||
dsi_generic_write_seq(dsi, 0xb3, 0x00, 0x00, 0x06);
|
||||
dsi_generic_write_seq(dsi, 0xd6, 0x01);
|
||||
|
||||
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(120);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(70);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4328_tianma_fhdplus_off(struct td4328_tianma_fhdplus *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(50);
|
||||
|
||||
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(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4328_tianma_fhdplus_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct td4328_tianma_fhdplus *ctx = to_td4328_tianma_fhdplus(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulators: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
td4328_tianma_fhdplus_reset(ctx);
|
||||
|
||||
ret = td4328_tianma_fhdplus_on(ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->prepared = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4328_tianma_fhdplus_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct td4328_tianma_fhdplus *ctx = to_td4328_tianma_fhdplus(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = td4328_tianma_fhdplus_off(ctx);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
|
||||
|
||||
ctx->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode td4328_tianma_fhdplus_mode = {
|
||||
.clock = (1080 + 76 + 4 + 20) * (2160 + 5 + 1 + 30) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 76,
|
||||
.hsync_end = 1080 + 76 + 4,
|
||||
.htotal = 1080 + 76 + 4 + 20,
|
||||
.vdisplay = 2160,
|
||||
.vsync_start = 2160 + 5,
|
||||
.vsync_end = 2160 + 5 + 1,
|
||||
.vtotal = 2160 + 5 + 1 + 30,
|
||||
.width_mm = 68,
|
||||
.height_mm = 136,
|
||||
};
|
||||
|
||||
static int td4328_tianma_fhdplus_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &td4328_tianma_fhdplus_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 td4328_tianma_fhdplus_panel_funcs = {
|
||||
.prepare = td4328_tianma_fhdplus_prepare,
|
||||
.unprepare = td4328_tianma_fhdplus_unprepare,
|
||||
.get_modes = td4328_tianma_fhdplus_get_modes,
|
||||
};
|
||||
|
||||
static int td4328_tianma_fhdplus_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct td4328_tianma_fhdplus *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->supplies[0].supply = "vdd";
|
||||
ctx->supplies[1].supply = "vddio";
|
||||
ctx->supplies[2].supply = "vsn";
|
||||
ctx->supplies[3].supply = "vsp";
|
||||
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
|
||||
ctx->supplies);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to get regulators\n");
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
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_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &td4328_tianma_fhdplus_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_of_backlight(&ctx->panel);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to get backlight\n");
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to attach to DSI host\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int td4328_tianma_fhdplus_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct td4328_tianma_fhdplus *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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id td4328_tianma_fhdplus_of_match[] = {
|
||||
{ .compatible = "sony,voyager-td4328-tianma" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, td4328_tianma_fhdplus_of_match);
|
||||
|
||||
static struct mipi_dsi_driver td4328_tianma_fhdplus_driver = {
|
||||
.probe = td4328_tianma_fhdplus_probe,
|
||||
.remove = td4328_tianma_fhdplus_remove,
|
||||
.driver = {
|
||||
.name = "panel-td4328-tianma-fhdplus",
|
||||
.of_match_table = td4328_tianma_fhdplus_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(td4328_tianma_fhdplus_driver);
|
||||
|
||||
MODULE_AUTHOR("Konrad Dybcio <konradybcio@gmail.com>");
|
||||
MODULE_DESCRIPTION("DRM driver for 7");
|
||||
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).
|
||||
|
|
|
|||
|
|
@ -242,6 +242,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,18 @@ config INPUT_PMIC8XXX_PWRKEY
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called pmic8xxx-pwrkey.
|
||||
|
||||
config INPUT_QCOM_SPMI_HAPTICS
|
||||
tristate "Qualcomm SPMI HAPTICS"
|
||||
depends on ARCH_QCOM
|
||||
depends on SPMI
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
This option enables support for the haptics found in pmi8998 and
|
||||
related PMICs. Based on the ff-memless interface.
|
||||
|
||||
To compile this driver as module, choose M here: the
|
||||
module will be called qcom_spmi_haptics.
|
||||
|
||||
config INPUT_SPARCSPKR
|
||||
tristate "SPARC Speaker support"
|
||||
depends on PCI && SPARC64
|
||||
|
|
|
|||
|
|
@ -64,6 +64,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_SPMI_HAPTICS) += qcom-spmi-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
|
||||
|
|
|
|||
981
drivers/input/misc/qcom-spmi-haptics.c
Normal file
981
drivers/input/misc/qcom-spmi-haptics.c
Normal file
|
|
@ -0,0 +1,981 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, Caleb Connolly <caleb@connolly.tech>
|
||||
* Qualcomm QPMI haptics driver for pmi8998 and related PMICs.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/input/qcom,spmi-haptics.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#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/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
|
||||
#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
|
||||
|
||||
enum hap_play_control {
|
||||
HAP_STOP,
|
||||
HAP_PAUSE,
|
||||
HAP_PLAY,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct spmi_haptics - struct for spmi haptics data.
|
||||
*
|
||||
* @dev: Our device parent.
|
||||
* @regmap: Register map for the hardware block.
|
||||
* @input_dev: The input device used to receive events.
|
||||
* @work: Work struct to play effects.
|
||||
* @base: Base address of the regmap.
|
||||
* @active: Atomic value used to track if haptics are currently playing.
|
||||
* @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).
|
||||
* @magnitude: The strength we should be playing at.
|
||||
* @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.
|
||||
* @wave_samp: The array of wave samples to write for buffer mode.
|
||||
* @brake_pat: The pattern to apply when braking.
|
||||
* @play_lock: Lock to be held when updating the hardware state.
|
||||
*/
|
||||
struct spmi_haptics {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct input_dev *haptics_input_dev;
|
||||
struct work_struct work;
|
||||
u32 base;
|
||||
|
||||
atomic_t active;
|
||||
|
||||
int play_irq;
|
||||
int sc_irq;
|
||||
ktime_t last_sc_time;
|
||||
u8 sc_count;
|
||||
|
||||
u8 actuator_type;
|
||||
u8 wave_shape;
|
||||
u8 play_mode;
|
||||
int magnitude;
|
||||
u32 vmax;
|
||||
u32 current_limit;
|
||||
u32 play_wave_rate;
|
||||
|
||||
u32 wave_samp[HAP_WAVE_SAMP_SET_LEN];
|
||||
u8 brake_pat[HAP_BRAKE_PAT_LEN];
|
||||
|
||||
struct mutex play_lock;
|
||||
};
|
||||
|
||||
static inline bool is_secure_addr(u16 addr)
|
||||
{
|
||||
return (addr & 0xFF) > 0xD0;
|
||||
}
|
||||
|
||||
static int spmi_haptics_read(struct spmi_haptics *haptics,
|
||||
u16 addr, u8 *val, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_bulk_read(haptics->regmap, addr, val, len);
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "Error reading address: 0x%x, ret %d\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spmi_haptics_write(struct spmi_haptics *haptics,
|
||||
u16 addr, u8 *val, int len)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
if (is_secure_addr(addr)) {
|
||||
for (i = 0; i < len; i++) {
|
||||
dev_dbg(haptics->dev, "%s: unlocking for addr: 0x%x, val: 0x%x", __func__,
|
||||
addr, val[i]);
|
||||
ret = regmap_write(haptics->regmap,
|
||||
haptics->base + HAP_SEC_ACCESS_REG, HAP_SEC_ACCESS_UNLOCK);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error writing unlock code, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_write(haptics->regmap, addr + i, val[i]);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error writing address 0x%x, ret %d\n",
|
||||
addr + i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (len > 1)
|
||||
ret = regmap_bulk_write(haptics->regmap, addr, val, len);
|
||||
else
|
||||
ret = regmap_write(haptics->regmap, addr, *val);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "%s: Error writing address: 0x%x, ret %d\n",
|
||||
__func__, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_masked(struct spmi_haptics *haptics,
|
||||
u16 addr, u8 mask, u8 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (is_secure_addr(addr)) {
|
||||
ret = regmap_write(haptics->regmap,
|
||||
haptics->base + HAP_SEC_ACCESS_REG, HAP_SEC_ACCESS_UNLOCK);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error writing unlock code - ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(haptics->regmap, addr, mask, val);
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "Error writing address: 0x%x - ret %d\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_haptics_idle(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
if (haptics->play_mode == HAP_PLAY_DIRECT ||
|
||||
haptics->play_mode == HAP_PLAY_PWM)
|
||||
return true;
|
||||
|
||||
ret = spmi_haptics_read(haptics, haptics->base + HAP_STATUS_1_REG, &val, 1);
|
||||
if (ret < 0 || (val & HAP_BUSY_BIT))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int spmi_haptics_module_enable(struct spmi_haptics *haptics, bool enable)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
dev_dbg(haptics->dev, "Setting module enable: %d", enable);
|
||||
|
||||
val = enable ? HAP_EN_BIT : 0;
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_EN_CTL_REG, &val, 1);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_vmax(struct spmi_haptics *haptics)
|
||||
{
|
||||
u8 val = 0;
|
||||
u32 vmax_mv = haptics->vmax;
|
||||
|
||||
vmax_mv = clamp_t(u32, vmax_mv, HAP_VMAX_MIN_MV, HAP_VMAX_MAX_MV);
|
||||
|
||||
dev_dbg(haptics->dev, "Setting vmax to: %d", vmax_mv);
|
||||
|
||||
val = DIV_ROUND_CLOSEST(vmax_mv, HAP_VMAX_MIN_MV);
|
||||
val = FIELD_PREP(HAP_VMAX_MASK, val);
|
||||
|
||||
// TODO: pm660 can enable overdrive here
|
||||
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_VMAX_CFG_REG,
|
||||
HAP_VMAX_MASK | HAP_WF_OVD_BIT, val);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_current_limit(struct spmi_haptics *haptics)
|
||||
{
|
||||
haptics->current_limit = clamp_t(u32, haptics->current_limit,
|
||||
HAP_ILIM_400_MA, HAP_ILIM_800_MA);
|
||||
|
||||
dev_dbg(haptics->dev, "Setting current_limit to: 0x%x", haptics->current_limit);
|
||||
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_ILIM_CFG_REG,
|
||||
HAP_ILIM_SEL_MASK, haptics->current_limit);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_play_mode(struct spmi_haptics *haptics)
|
||||
{
|
||||
u8 val = 0;
|
||||
|
||||
if (!is_haptics_idle(haptics))
|
||||
return -EBUSY;
|
||||
|
||||
dev_dbg(haptics->dev, "Setting play_mode to: 0x%x", haptics->play_mode);
|
||||
|
||||
val = FIELD_PREP(HAP_WF_SOURCE_MASK, haptics->play_mode);
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_SEL_REG,
|
||||
HAP_WF_SOURCE_MASK, val);
|
||||
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_play_rate(struct spmi_haptics *haptics, u16 play_rate)
|
||||
{
|
||||
u8 val[2];
|
||||
|
||||
dev_dbg(haptics->dev, "Setting play_rate to: %d", play_rate);
|
||||
|
||||
val[0] = FIELD_PREP(HAP_RATE_CFG1_MASK, play_rate);
|
||||
val[1] = FIELD_PREP(HAP_RATE_CFG2_MASK, play_rate >> HAP_RATE_CFG2_SHIFT);
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_RATE_CFG1_REG, val, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* spmi_haptics_set_auto_res() - Auto resonance
|
||||
* allows the haptics to automatically adjust the
|
||||
* speed of the oscillation in order to maintain
|
||||
* the resonant frequency.
|
||||
*/
|
||||
static int spmi_haptics_set_auto_res(struct spmi_haptics *haptics, bool enable)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
// LRAs are the only type to support auto res
|
||||
if (haptics->actuator_type != HAP_TYPE_LRA)
|
||||
return 0;
|
||||
|
||||
val = enable ? AUTO_RES_EN_BIT : 0;
|
||||
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_TEST2_REG,
|
||||
AUTO_RES_EN_BIT, val);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_brake(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret, i;
|
||||
u8 val;
|
||||
|
||||
dev_dbg(haptics->dev, "Configuring brake pattern");
|
||||
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_EN_CTL2_REG,
|
||||
BRAKE_EN_BIT, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = HAP_BRAKE_PAT_LEN - 1, val = 0; i >= 0; i--) {
|
||||
u8 p = haptics->brake_pat[i] & HAP_BRAKE_PAT_MASK;
|
||||
|
||||
val |= p << (i * 2);
|
||||
}
|
||||
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_BRAKE_REG, &val, 1);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_buffer_config(struct spmi_haptics *haptics)
|
||||
{
|
||||
u8 buf[HAP_WAVE_SAMP_LEN];
|
||||
int i;
|
||||
|
||||
dev_dbg(haptics->dev, "Writing buffer config");
|
||||
|
||||
for (i = 0; i < HAP_WAVE_SAMP_LEN; i++)
|
||||
buf[i] = haptics->wave_samp[i];
|
||||
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_WF_S1_REG, buf,
|
||||
HAP_WAVE_SAMP_LEN);
|
||||
}
|
||||
|
||||
/*
|
||||
* spmi_haptics_write_wave_repeat() - write wave repeat values.
|
||||
*/
|
||||
static int spmi_haptics_write_wave_repeat(struct spmi_haptics *haptics)
|
||||
{
|
||||
u8 val, mask;
|
||||
|
||||
/* The number of times to repeat each wave */
|
||||
mask = WF_REPEAT_MASK | WF_S_REPEAT_MASK;
|
||||
val = FIELD_PREP(WF_REPEAT_MASK, 0) |
|
||||
FIELD_PREP(WF_S_REPEAT_MASK, 0);
|
||||
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_WF_REPEAT_REG,
|
||||
mask, val);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_play_control(struct spmi_haptics *haptics,
|
||||
enum hap_play_control ctrl)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
switch (ctrl) {
|
||||
case HAP_STOP:
|
||||
val = 0;
|
||||
break;
|
||||
case HAP_PAUSE:
|
||||
val = HAP_PAUSE_BIT;
|
||||
break;
|
||||
case HAP_PLAY:
|
||||
val = HAP_PLAY_BIT;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_dbg(haptics->dev, "haptics play ctrl: %d\n", ctrl);
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_PLAY_REG, &val, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 spmi_haptics_play_irq_handler(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 spmi_haptics_sc_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct spmi_haptics *haptics = data;
|
||||
int ret;
|
||||
u8 val;
|
||||
s64 sc_delta_time_us;
|
||||
ktime_t temp;
|
||||
|
||||
ret = spmi_haptics_read(haptics, haptics->base + HAP_STATUS_1_REG, &val, 1);
|
||||
if (ret < 0)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
if (!(val & SC_FLAG_BIT)) {
|
||||
haptics->sc_count = 0;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
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++;
|
||||
|
||||
// Clear the interrupt flag
|
||||
val = SC_CLR_BIT;
|
||||
ret = spmi_haptics_write(haptics, haptics->base + HAP_SC_CLR_REG, &val, 1);
|
||||
if (ret < 0)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
if (haptics->sc_count > SC_MAX_COUNT) {
|
||||
dev_crit(haptics->dev, "Short circuit persists, disabling haptics\n");
|
||||
ret = spmi_haptics_module_enable(haptics, false);
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "Error disabling module, rc=%d\n", ret);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* spmi_haptics_init() - Initialise haptics hardware for use
|
||||
* @haptics: haptics device
|
||||
* Returns: 0 on success, < 0 on error
|
||||
*/
|
||||
static int spmi_haptics_init(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
u8 val, mask;
|
||||
u16 play_rate;
|
||||
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_CFG1_REG,
|
||||
HAP_ACT_TYPE_MASK, haptics->actuator_type);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Configure auto resonance
|
||||
* see spmi_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 = spmi_haptics_write_masked(haptics, haptics->base + HAP_LRA_AUTO_RES_REG,
|
||||
mask, val);
|
||||
|
||||
/* Configure the PLAY MODE register */
|
||||
ret = spmi_haptics_write_play_mode(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = spmi_haptics_write_vmax(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Configure the ILIM register */
|
||||
ret = spmi_haptics_write_current_limit(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// Configure the debounce for short-circuit detection.
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_SC_DEB_REG,
|
||||
HAP_SC_DEB_MASK, HAP_SC_DEB_CYCLES_MAX);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// write the wave shape
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_CFG2_REG,
|
||||
HAP_LRA_RES_TYPE_MASK, haptics->wave_shape);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
play_rate = haptics->play_wave_rate / HAP_RATE_CFG_STEP_US;
|
||||
|
||||
/*
|
||||
* Configure RATE_CFG1 and RATE_CFG2 registers.
|
||||
* Note: For ERM these registers act as play rate and
|
||||
* for LRA these represent resonance period
|
||||
*/
|
||||
ret = spmi_haptics_write_play_rate(haptics, play_rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = spmi_haptics_write_brake(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (haptics->play_mode == HAP_PLAY_BUFFER) {
|
||||
ret = spmi_haptics_write_wave_repeat(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = spmi_haptics_write_buffer_config(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (haptics->play_irq >= 0) {
|
||||
dev_dbg(haptics->dev, "%s: Requesting play IRQ, irq: %d", __func__,
|
||||
haptics->play_irq);
|
||||
ret = devm_request_threaded_irq(haptics->dev, haptics->play_irq,
|
||||
NULL, spmi_haptics_play_irq_handler, IRQF_ONESHOT,
|
||||
"haptics_play_irq", haptics);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Unable to request play IRQ ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* use play_irq only for buffer mode */
|
||||
if (haptics->play_mode != HAP_PLAY_BUFFER)
|
||||
disable_irq(haptics->play_irq);
|
||||
}
|
||||
|
||||
if (haptics->sc_irq >= 0) {
|
||||
dev_dbg(haptics->dev, "%s: Requesting play IRQ, irq: %d", __func__,
|
||||
haptics->play_irq);
|
||||
ret = devm_request_threaded_irq(haptics->dev, haptics->sc_irq,
|
||||
NULL, spmi_haptics_sc_irq_handler, IRQF_ONESHOT,
|
||||
"haptics_sc_irq", haptics);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Unable to request sc IRQ ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_enable - handler to start/stop vibration
|
||||
* @haptics: pointer to haptics struct
|
||||
* @enable: state to set
|
||||
* Returns: 0 on success, < 0 on failure
|
||||
*/
|
||||
static int spmi_haptics_enable(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&haptics->play_lock);
|
||||
if (haptics->sc_count > SC_MAX_COUNT) {
|
||||
dev_err(haptics->dev, "Can't play while in short circuit");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
ret = spmi_haptics_set_auto_res(haptics, false);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error disabling auto_res, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = spmi_haptics_module_enable(haptics, true);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error enabling module, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = spmi_haptics_write_play_control(haptics, HAP_PLAY);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error enabling play, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = spmi_haptics_set_auto_res(haptics, true);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error enabling auto_res, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&haptics->play_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_enable - handler to start/stop vibration
|
||||
* @haptics: pointer to haptics struct
|
||||
* @enable: state to set
|
||||
* Returns: 0 on success, < 0 on failure
|
||||
*/
|
||||
static int spmi_haptics_disable(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&haptics->play_lock);
|
||||
|
||||
ret = spmi_haptics_write_play_control(haptics, HAP_STOP);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error disabling play, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = spmi_haptics_module_enable(haptics, false);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error disabling module, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&haptics->play_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Threaded function to update the haptics state.
|
||||
*/
|
||||
static void spmi_haptics_work(struct work_struct *work)
|
||||
{
|
||||
struct spmi_haptics *haptics = container_of(work, struct spmi_haptics, work);
|
||||
|
||||
int ret;
|
||||
bool enable;
|
||||
|
||||
enable = atomic_read(&haptics->active);
|
||||
dev_dbg(haptics->dev, "%s: state: %d\n", __func__, enable);
|
||||
|
||||
if (enable)
|
||||
ret = spmi_haptics_enable(haptics);
|
||||
else
|
||||
ret = spmi_haptics_disable(haptics);
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "Error setting haptics, ret=%d", ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if (atomic_read(&haptics->active)) {
|
||||
atomic_set(&haptics->active, 0);
|
||||
schedule_work(&haptics->work);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_play_effect - play haptics effects
|
||||
* @dev: input device pointer
|
||||
* @data: data of effect
|
||||
* @effect: effect to play
|
||||
*/
|
||||
static int spmi_haptics_play_effect(struct input_dev *dev, void *data,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
struct spmi_haptics *haptics = input_get_drvdata(dev);
|
||||
|
||||
dev_dbg(haptics->dev, "%s: Rumbling with strong: %d and weak: %d", __func__,
|
||||
effect->u.rumble.strong_magnitude, effect->u.rumble.weak_magnitude);
|
||||
|
||||
haptics->magnitude = effect->u.rumble.strong_magnitude >> 8;
|
||||
if (!haptics->magnitude)
|
||||
haptics->magnitude = effect->u.rumble.weak_magnitude >> 10;
|
||||
|
||||
if (!haptics->magnitude) {
|
||||
atomic_set(&haptics->active, 0);
|
||||
goto end;
|
||||
}
|
||||
|
||||
atomic_set(&haptics->active, 1);
|
||||
|
||||
haptics->vmax = ((HAP_VMAX_MAX_MV - HAP_VMAX_MIN_MV) * haptics->magnitude) / 100 +
|
||||
HAP_VMAX_MIN_MV;
|
||||
|
||||
dev_dbg(haptics->dev, "%s: magnitude: %d, vmax: %d", __func__,
|
||||
haptics->magnitude, haptics->vmax);
|
||||
|
||||
spmi_haptics_write_vmax(haptics);
|
||||
|
||||
end:
|
||||
schedule_work(&haptics->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spmi_haptics_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct spmi_haptics *haptics;
|
||||
struct device_node *node;
|
||||
struct input_dev *input_dev;
|
||||
int ret;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
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;
|
||||
|
||||
node = pdev->dev.of_node;
|
||||
|
||||
haptics->dev = &pdev->dev;
|
||||
|
||||
ret = of_property_read_u32(node, "reg", &haptics->base);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Couldn't find reg in node = %s ret = %d\n",
|
||||
node->full_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
haptics->play_irq = platform_get_irq_byname(pdev, "play");
|
||||
if (haptics->play_irq < 0) {
|
||||
dev_err(&pdev->dev, "Unable to get play irq\n");
|
||||
ret = haptics->play_irq;
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
haptics->sc_irq = platform_get_irq_byname(pdev, "short");
|
||||
if (haptics->sc_irq < 0) {
|
||||
dev_err(&pdev->dev, "Unable to get sc irq\n");
|
||||
ret = haptics->sc_irq;
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
// We only support LRAs for now
|
||||
haptics->actuator_type = HAP_TYPE_LRA;
|
||||
ret = of_property_read_u32(node, "qcom,actuator-type", &val);
|
||||
if (!ret) {
|
||||
if (val != HAP_TYPE_LRA) {
|
||||
dev_err(&pdev->dev, "qcom,actuator-type (%d) isn't supported\n", val);
|
||||
ret = -EINVAL;
|
||||
goto register_fail;
|
||||
}
|
||||
haptics->actuator_type = val;
|
||||
}
|
||||
|
||||
// Only buffer mode is currently supported
|
||||
haptics->play_mode = HAP_PLAY_BUFFER;
|
||||
ret = of_property_read_u32(node, "qcom,play-mode", &val);
|
||||
if (!ret) {
|
||||
if (val != HAP_PLAY_BUFFER) {
|
||||
dev_err(&pdev->dev, "qcom,play-mode (%d) isn't supported\n", val);
|
||||
ret = -EINVAL;
|
||||
goto register_fail;
|
||||
}
|
||||
haptics->play_mode = val;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "qcom,wave-play-rate-us", &val);
|
||||
if (!ret) {
|
||||
haptics->play_wave_rate = val;
|
||||
} else if (ret != -EINVAL) {
|
||||
dev_err(haptics->dev, "Unable to read play rate ret=%d\n", ret);
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
haptics->play_wave_rate =
|
||||
clamp_t(u32, haptics->play_wave_rate,
|
||||
HAP_WAVE_PLAY_RATE_MIN_US, HAP_WAVE_PLAY_RATE_MAX_US);
|
||||
|
||||
haptics->wave_shape = HAP_WAVE_SINE;
|
||||
ret = of_property_read_u32(node, "qcom,wave-shape", &val);
|
||||
if (!ret) {
|
||||
if (val != HAP_WAVE_SINE && val != HAP_WAVE_SQUARE) {
|
||||
dev_err(&pdev->dev, "qcom,wave-shape is invalid: %d\n", val);
|
||||
ret = -EINVAL;
|
||||
goto register_fail;
|
||||
}
|
||||
haptics->wave_shape = val;
|
||||
}
|
||||
|
||||
haptics->brake_pat[0] = 0x3;
|
||||
haptics->brake_pat[1] = 0x3;
|
||||
haptics->brake_pat[2] = 0x2;
|
||||
haptics->brake_pat[3] = 0x1;
|
||||
|
||||
ret = of_property_read_u8_array(node, "qcom,brake-pattern", haptics->brake_pat, 4);
|
||||
if (ret < 0 && ret != -EINVAL) {
|
||||
dev_err(&pdev->dev, "qcom,brake-pattern is invalid, ret = %d\n", ret);
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
haptics->current_limit = HAP_ILIM_400_MA;
|
||||
|
||||
for (i = 0; i < HAP_WAVE_SAMP_LEN; i++)
|
||||
haptics->wave_samp[i] = HAP_WF_SAMP_MAX;
|
||||
|
||||
ret = spmi_haptics_init(haptics);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Error initialising haptics, ret=%d\n",
|
||||
ret);
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, haptics);
|
||||
|
||||
input_dev = devm_input_allocate_device(&pdev->dev);
|
||||
if (!input_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&haptics->work, spmi_haptics_work);
|
||||
haptics->haptics_input_dev = input_dev;
|
||||
|
||||
input_dev->name = "spmi_haptics";
|
||||
input_dev->id.version = 1;
|
||||
input_dev->close = spmi_haptics_close;
|
||||
input_set_drvdata(input_dev, haptics);
|
||||
// Figure out how to make this FF_PERIODIC
|
||||
input_set_capability(haptics->haptics_input_dev, EV_FF, FF_RUMBLE);
|
||||
|
||||
ret = input_ff_create_memless(input_dev, NULL,
|
||||
spmi_haptics_play_effect);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't register vibrator as FF device\n");
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
ret = input_register_device(input_dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "couldn't register input device\n");
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
register_fail:
|
||||
cancel_work_sync(&haptics->work);
|
||||
mutex_destroy(&haptics->play_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused spmi_haptics_suspend(struct device *dev)
|
||||
{
|
||||
struct spmi_haptics *haptics = dev_get_drvdata(dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
spmi_haptics_disable(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->haptics_input_dev);
|
||||
|
||||
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);
|
||||
|
||||
spmi_haptics_disable(haptics);
|
||||
}
|
||||
|
||||
static const struct of_device_id spmi_haptics_match_table[] = {
|
||||
{ .compatible = "qcom,spmi-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 v2");
|
||||
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;
|
||||
|
|
|
|||
180
drivers/input/rmi4/rmi_f1a.c
Normal file
180
drivers/input/rmi4/rmi_f1a.c
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
// 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__);
|
||||
|
||||
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,
|
||||
};
|
||||
|
|
@ -638,6 +638,18 @@ config TOUCHSCREEN_MTOUCH
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called mtouch.
|
||||
|
||||
config TOUCHSCREEN_NT36XXX
|
||||
tristate "Novatek NT36XXX In-Cell I2C touchscreen controller"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here if you have a Novatek NT36xxx series In-Cell
|
||||
touchscreen connected to your system over I2C.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called nt36xxx.
|
||||
|
||||
config TOUCHSCREEN_IMX6UL_TSC
|
||||
tristate "Freescale i.MX6UL touchscreen controller"
|
||||
depends on ((OF && GPIOLIB) || COMPILE_TEST) && HAS_IOMEM
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o
|
|||
obj-$(CONFIG_TOUCHSCREEN_MSG2638) += msg2638.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_NT36XXX) += nt36xxx.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue