Compare commits

...

26 Commits

Author SHA1 Message Date
5358f50837 t210b01: disable actmon and interconnects
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:23 +00:00
4f8b7d41ad t210b01: override pcie compatible
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:22 +00:00
536a60889d pci: tegra: add t210b01 support
This commit also fixes configuration checks

Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:22 +00:00
255e0f9183 typec: introduce bm92txx driver
TODO: fix commit
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:22 +00:00
718d907b59 [DEBUG] xusb-tegra
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:21 +00:00
8cd5b04d6e t210b01: add emc support
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:21 +00:00
9058cf8e44 memory: tegra186-emc: support t210b01
Tegra210b01 uses Tegra186 style emc management, as in it is
offloaded to BPMP. This driver already implements this, so no
reason to shoehorn in elsewhere.

Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:21 +00:00
8e6a4ab49e abi
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:20 +00:00
d0c8af92e0 t210b01: add sdmmc suport
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:20 +00:00
e2e87d0cf7 nouveau: add tegra210b01 support
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:20 +00:00
9417244eb3 tegra210b01: do not enable venc
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:20 +00:00
a6d426fded tegra: pmc: fix t210b01 pmc support
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:19 +00:00
7f1e672cff tegra-drm: add t210b01 dsi support
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:19 +00:00
1a9c3cd738 enable max77812
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:19 +00:00
azkali
aca6072a76 panel: dsi-nx: Add dsi-nx panel driver
dsi-nx is a new blanket driver for panels on the Nintendo Switch.
The Switch boots Linux via the "hekate" custom bootloader, which
performs panel initialization and passes panel info to kernel.

This driver is based on panel-jdi-lpm062m326a by SwitchR.

Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:18 +00:00
6ec3530c00 t210: add core dvfs floor/cap
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:18 +00:00
7f9577cec5 tegra: dfll: forward-port 4.9 dfll
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:18 +00:00
Laxman Dewangan
0b57a72543 regulator: core: add API to get min/max voltage for rails
Add API to get min/max rail voltage configured from platform for
given rails. This will help to set the pad voltage based on platform
specific power tree.

bug 200083043

Change-Id: I054734ca2a25b5c830525e27ab22e43534f67351
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/712001
(cherry picked from commit c0d1de0da091132d037e1bb32f2ee09b5c00369b)
Reviewed-on: http://git-master/r/1119836
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:18 +00:00
Alex Frid
78a3979426 clk: Add parent change notifications
Added parent change notifications to be used when drivers behavior
depends on physical nature of the parent, not just clock rate it
supplies (e.g., selection of Tegra DFLL as CPU clock source changes
mechanism of voltage control even if the clock rate stays the same
as on PLL).

Bug 200269751

Change-Id: I617c94927ef437caf240efd91497b49ad6f5c39d
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1573111
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
Reviewed-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Tested-by: Peter De Schrijver <pdeschrijver@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: Timo Alho <talho@nvidia.com>
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:17 +00:00
Alex Frid
a37c367e1a clk: tegra: Add subtree change notifications
Added PRE_SUBTREE_CHANGE and POST_SUBTREE_CHANGE that called before
and after rate change is propagated down the sub-tree rooted in clk.
This would allow children to be aware that next set rate operation
is triggered by downward rate propagation, rather than direct set rate
on a child clock.

Bug 200267979

Change-Id: I6f2acbeca7cead0ecd385dcb2e58ced32448e998
Signed-off-by: Alex Frid <afrid@nvidia.com>
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
(cherry picked from commit 62f0d763fcb6c9d5bd9a373d22d802503ab0fdc5)
Reviewed-on: https://git-master.nvidia.com/r/1558143
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Timo Alho <talho@nvidia.com>
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:17 +00:00
8a08c5af63 tegra: dfll: use tune1_low
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:17 +00:00
Jon Hunter
b3f48191fc soc/tegra: update sppedo and chip rev handling
- Make revisions consistent
- Enable T210B01 support
- Update speedo structs

soc/tegra: fuse: Add support for retrieving IDDQ information

Add helpers functions for retrieving IDDQ information which is used
by SYSEDP.

Bug 1811732

Change-Id: I889afecebc9b6d7c2085a528f5dfb58a095165ff
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-on: http://git-master/r/1255677

Conflicts:
	include/linux/tegra-fuse.h

soc: tegra: Don't confuse chip / speedo revisions

During T210 DVFS initialization SoC chip revision was incorrectly used
instead of speedo fuse revision to limit core maximum voltage. Fixed it
in this commit.

Bug 200269751
Bug 200277489

Change-Id: Ifadabb1840039f407d2abfd8b9a8782b865b5a13
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/1302687
Reviewed-on: https://git-master.nvidia.com/r/1563340
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Tested-by: Sachin Nikam <snikam@nvidia.com>

soc: tegra: Fix for Automotive speedo/process ids

This fixes to derive correct speedo/process ids for
automotive skus(0x17 and 0x23).

Also display the sku info in hexadecimal format.

Bug 200258423

Change-Id: Ifab5f957983494fcffeb253f7fdda6b6062c56c5
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1576315
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: Timo Alho <talho@nvidia.com>

soc: fuse: Introduce T210b01 speedo IDs

Introduce T210b01 speedo ID initialization by implementing:

- Parse T210b01 speedo fuses programming revision from spare fuses
- T210b01 binning thresholds
- Detection of T210b01 SKUs

Bug 1906940

Change-Id: If7d168434c12b5e92250be608f9736fc80cc2886
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1576317
Reviewed-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Tested-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>

soc/tegra: fuse: update speedo IDs for Tegra210

Bug 200255986

[ There's a merge conflict during the cherry-pick from Kernel 4.4
  to 4.9 becauase a later patch got merged first -- Nicolin ]

Change-Id: Iacf188f4cccea03d3a82f7ad18455c18681c506d
Signed-off-by: Joseph Lo <josephl@nvidia.com>
Reviewed-on: http://git-master/r/1262213
Reviewed-by: Shreshtha Sahu <ssahu@nvidia.com>
Reviewed-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
GVS: Gerrit_Virtual_Submit
(cherry picked from commit 98a6b47e55b1e5754490420c1ca379793e3569d2)
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1578888
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>

soc: tegra: Update T210 sku info

- Populated sku info ucm field, and selected DVFS ids appropriately
- Made "a02" DVFS ids selection forward looking
  (applied to all A02+ revisions)
- Applied vcm31_sku to a02 parts (was a01 only), but limit it to
  0x17 sku fuses (was applied to 0x07 and 0x13 as well)
- Made always on personality a must for sku 0x8F

Bug 200269751

Change-Id: I85cbe2f1621c271640643aa2d203b9dac5b8c992
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/1307422
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Reviewed-by: Jon Mayo <jmayo@nvidia.com>
(cherry picked from commit 9ffc1f1cc2cb588f440640921f77223a6baee280)
Reviewed-on: https://git-master.nvidia.com/r/1578889
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Timo Alho <talho@nvidia.com>

soc: tegra: Add support for T210 sku 0x1F

Bug 2059069

Change-Id: I7d20b6f1b889a18f23ae2fe6662d7b08e950154e
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1669017
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bo Yan <byan@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>

clk: soc: tegra: Add support for T210b01 sku 0x87

Bug 2075533

Change-Id: I07433bd7139a5c845065a9a1d46f5f6e9559fbb5
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1669169
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bo Yan <byan@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>

soc: tegra: Add usage mode UCM field to sku info

Bug 200269751
Bug 200277498
Bug 200340064

Change-Id: I8044b350587e2298ec1b705dd01fec5fc6d83379
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/1307421
Signed-off-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1563330
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit

soc/tegra: add support for getting b01 rev

soc/tegra: adjust revision handling for t210 skus

Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:16 +00:00
Alex Frid
46093863d5 clk: soc: tegra: Rename DFLL tune1 to tune1_low
Renamed DFLL tune1 to tune1_low to be consistent with
tune0_low/tune0_high naming convention.

Bug 1967884

Change-Id: If23170305143b05c2918e04691c73fe13b777272
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1576306
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:16 +00:00
c4f897149e arm64: t210b01: enable max77812
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:16 +00:00
81343aa1fd arm64: t210b01: add max77620 support
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:16 +00:00
6334568c2f arm64: t210: add initial support for nx
The Nintendo Switch is a video game console based on the
Tegra X1 (T210) and X1+ (T210B01).

Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-02 00:10:15 +00:00
48 changed files with 11587 additions and 815 deletions

View File

@@ -26,7 +26,11 @@ dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3450-0000.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3541-0000.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-smaug.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2894-0050-a08.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-odin.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210b01-p2894-0050-a08.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210b01-odin.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210b01-vali.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210b01-fric.dtb
dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-0000.dtb
dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p3509-0000+p3636-0001.dtb
dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p2972-0000.dtb

View File

@@ -0,0 +1,944 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include <dt-bindings/mfd/max77620.h>
#include <dt-bindings/gpio/tegra-gpio.h>
#include <dt-bindings/thermal/thermal.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/soc/tegra-pmc.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include "tegra210.dtsi"
/ {
aliases {
i2c1 = "/i2c@7000c000";
i2c2 = "/i2c@7000c400";
i2c3 = "/i2c@7000c500";
i2c5 = "/i2c@7000d000";
rtc0 = "/i2c@7000d000/max77620@3c";
rtc1 = "/rtc@7000e000";
serial0 = &uarta;
serial1 = &uartb;
serial2 = &uartc;
serial3 = &uartd;
};
chosen {
bootargs = "root=/dev/mmcblk0p2 rw rootwait fbcon=rotate:3 printk.synchronous=1 loglevel=4 console=fb0 console=ttyGS0 earlycon";
stdout-path = "serial1:115200n8";
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
vdd-cpu-supply = <&cpu_max_reg>;
};
idle-states {
cpu-sleep {
status = "okay";
};
};
};
gpu@57000000 {
status = "okay";
vdd-supply = <&gpu_max_reg>;
};
host1x@50000000 {
dsia: dsi@54300000 {
status = "okay";
panel@0 {
compatible = "jdi,lpm062m326a";
reset-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
backlight = <&backlight>;
vdd1-supply = <&v_pavdd_5v0>;
vdd2-supply = <&v_navdd_5v0>;
};
};
/* tegradc.0: DSI */
dc@54200000 {
status = "okay";
pavdd_lcd-supply = <&v_pavdd_5v0>;
navdd_lcd-supply = <&v_navdd_5v0>;
dvdd_lcd-supply = <&max77620_sd3>;
vdd_lcd_bl_en-supply = <&lcd_bl_en>;
nvidia,outputs = <&dsia>;
};
/* tegradc.1: DP */
dc@54240000 {
status = "okay";
avdd_hdmi-supply = <&max77620_ldo8>; /* 1V05 */
avdd_hdmi_pll-supply = <&max77620_sd3>; /* 1V8 */
// vdd_hdmi_5v0-supply = <&vdd_hdmi>; /* 5V0 GPIO_PCC7 fixed reg */
vdd-dp-pwr-supply = <&vdd_3v3>;
avdd-dp-pll-supply = <&max77620_sd3>;
vdd-dp-pad-supply = <&max77620_ldo8>;
extcon-cables = <&bm92t 3>;
extcon-cable-names = "typec1";
nvidia,outputs = <&sor1>;
};
dpaux1: dpaux@54040000 {
status = "okay";
vdd-supply = <&v_pavdd_5v0>;
};
sor1: sor@54580000 {
status = "okay";
nvidia,dpaux = <&dpaux1>;
avdd-io-hdmi-dp-supply = <&max77620_ldo8>;
vdd-hdmi-dp-pll-supply = <&max77620_sd3>;
nvidia,hpd-gpio = <&gpio TEGRA_GPIO(CC, 1) GPIO_ACTIVE_LOW>;
};
vi: i2c@546c0000 {
status = "okay";
};
};
clock@70110000 {
status = "okay";
nvidia,cf = <6>;
nvidia,ci = <0>;
nvidia,cg = <2>;
nvidia,droop-ctrl = <0x00000f00>;
nvidia,force-mode = <1>;
nvidia,i2c-fs-rate = <400000>;
nvidia,sample-rate = <12500>;
vdd-cpu-supply = <&cpu_max_reg>;
};
memory {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0x80000000>;
};
reserved-memory {
/delete-node/ vpr-carveout;
/delete-node/ iram-carveout;
};
r2p {
compatible = "tegra-r2p";
status = "okay";
};
/* debug port */
serial@70006000 {
status = "disabled";
};
/* joycon ports:
invert TXD and RTS via IRDA_CSR
start @ 1000000 baud, switch to 3000000
when they are >= 3000000 baud, use 2 stop bits
use flow control
Note: hsuart driver is required for flow control
*/
/* right joycon */
serial@70006040 {
status = "okay";
compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart";
nvidia,invert-txd;
nvidia,invert-rts;
reset-names = "serial";
joyconr {
status = "okay";
compatible = "nintendo,joycon-serdev";
charger-supply = <&en_vdd_jcr_chgr>;
detect-en-gpios = <&gpio TEGRA_GPIO(G, 0) GPIO_ACTIVE_HIGH>;
detect-gpios = <&gpio TEGRA_GPIO(H, 6) GPIO_ACTIVE_LOW>;
};
};
/* left joycon */
serial@70006200 {
status = "okay";
compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart";
nvidia,invert-txd;
nvidia,invert-rts;
reset-names = "serial";
joyconl {
status = "okay";
compatible = "nintendo,joycon-serdev";
charger-supply = <&en_vdd_jcl_chgr>;
detect-en-gpios = <&gpio TEGRA_GPIO(D, 1) GPIO_ACTIVE_HIGH>;
detect-gpios = <&gpio TEGRA_GPIO(E, 6) GPIO_ACTIVE_LOW>;
};
};
/* bluetooth */
serial@70006300 {
dma-names = "tx";
status = "okay";
compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart";
reset-names = "serial";
bluetooth {
compatible = "brcm,bcm43438-bt";
vbat-supply = <&battery_reg>;
vddio-supply = <&battery_reg>;
shutdown-gpios = <&gpio TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
device-wakeup-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_LOW>;
max-speed = <3000000>; /* Max supported 4 MBaud */
sco-routing = <1>; /* Over HCI */
};
};
clk32k_in: clock-32k {
compatible = "fixed-clock";
clock-frequency = <32768>;
#clock-cells = <0>;
};
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm 0 33898>;
pwm-names = "backlight";
brightness-levels = <
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40 41 42 43 44
45 46 47 48 49 50 51 52 53 54 55 56 57 58
59 60 61 62 63 64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81 82 83 84 85 86
87 88 89 90 91 92 93 94 95 96 97 98 99 100
>;
default-brightness-level = <50>;
enable-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
power-supply = <&max77620_sd3>;
};
/* Fixed regulators */
battery_reg: vdd-ac-bat {
compatible = "regulator-fixed";
status = "okay";
regulator-name = "vdd-ac-bat";
regulator-min-microvolt = <4800000>;
regulator-max-microvolt = <4800000>;
regulator-always-on;
regulator-boot-on;
};
vdd_3v3: vdd-3v3 {
compatible = "regulator-fixed";
regulator-name = "vdd-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
gpio = <&max77620 3 0>;
enable-active-high;
regulator-enable-ramp-delay = <160>;
regulator-disable-ramp-delay = <10000>;
};
max77620_gpio7: avdd-dsi-csi-1v2 {
compatible = "regulator-fixed";
regulator-name = "max77620-gpio7";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-boot-on; /* Must be set for seamless display */
gpio = <&max77620 7 0>;
enable-active-high;
regulator-enable-ramp-delay = <240>;
regulator-disable-ramp-delay = <11340>;
vin-supply = <&max77620_ldo0>;
};
lcd_bl_en: lcd-bl-en {
compatible = "regulator-fixed";
regulator-name = "lcd-bl-en";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
gpio = <&gpio TEGRA_GPIO(V, 1) 0>;
regulator-boot-on; /* Must be set for seamless display */
enable-active-high;
regulator-always-on;
regulator-state-mem {
regulator-off-in-suspend;
};
};
en_vdd_sd: en-vdd-sd {
compatible = "regulator-fixed";
regulator-name = "en-vdd-sd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio TEGRA_GPIO(E, 4) 0>;
enable-active-high;
regulator-enable-ramp-delay = <472>;
regulator-disable-ramp-delay = <4880>;
vin-supply = <&vdd_3v3>;
};
/* LCD Power Enable +5V. Rohm BD8316GWL. */
v_pavdd_5v0: v-pavdd-5v0 {
compatible = "regulator-fixed";
regulator-name = "v_pavdd_5v0";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
gpio = <&gpio TEGRA_GPIO(I, 0) 0>;
enable-active-high;
regulator-boot-on; /* Must be set for seamless display */
regulator-enable-ramp-delay = <232>;
};
/* LCD Power Enable -5V. Rohm BD8316GWL. */
v_navdd_5v0: v-navdd-5v0 {
compatible = "regulator-fixed";
regulator-name = "v_navdd_5v0";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
gpio = <&gpio TEGRA_GPIO(I, 1) 0>;
enable-active-high;
regulator-boot-on; /* Must be set for seamless display */
regulator-enable-ramp-delay = <232>;
};
/* Joycon/Fan power (battery). Maxim MAX8969EWL53+. */
v_vdd50_a: v-vdd50-a {
compatible = "regulator-fixed";
regulator-name = "v_vdd50_a";
regulator-min-microvolt = <5300000>;
regulator-max-microvolt = <5300000>;
gpio = <&gpio TEGRA_GPIO(A, 5) 0>;
enable-active-high;
};
/* Joycon/Fan power (usb). DC0 on Odin. Maxim MAX8969EWL53+ on Modin. */
v_vdd50_b: v-vdd50-b {
compatible = "regulator-fixed";
regulator-name = "v_vdd50_b";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio TEGRA_GPIO(CC, 4) 0>;
enable-active-high;
};
v_vdd5v3: v-vdd5v3 {
compatible = "regulator-fixed";
status = "okay"; /* Only enabled on Modin/Vali/Fric */
regulator-name = "v_vdd5v3";
regulator-min-microvolt = <5300000>;
regulator-max-microvolt = <5300000>;
gpio = <&gpio TEGRA_GPIO(X, 3) 0>;
enable-active-high;
regulator-enable-ramp-delay = <10000>;
};
vdd3v3_gc: vdd3v3-gc {
compatible = "regulator-fixed";
regulator-name = "vdd3v3_gc";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio TEGRA_GPIO(E, 5) 0>;
enable-active-high;
regulator-enable-ramp-delay = <472>;
regulator-disable-ramp-delay = <4880>;
vin-supply = <&vdd_3v3>;
};
/* TI TCR2EE48 4.8V */
en_vdd_jcl_chgr: left-joycon-charger {
compatible = "regulator-fixed";
status = "okay";
regulator-name = "left-joycon-charger";
regulator-min-microvolt = <4800000>;
regulator-max-microvolt = <4800000>;
gpio = <&gpio TEGRA_GPIO(CC, 3) GPIO_ACTIVE_HIGH>;
enable-active-high;
vin-supply = <&v_vdd50_a>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
/* TI TCR2EE48 4.8V */
en_vdd_jcr_chgr: right-joycon-charger {
compatible = "regulator-fixed";
status = "okay";
regulator-name = "right-joycon-charger";
regulator-min-microvolt = <4800000>;
regulator-max-microvolt = <4800000>;
gpio = <&gpio TEGRA_GPIO(K, 3) GPIO_ACTIVE_HIGH>;
enable-active-high;
vin-supply = <&v_vdd50_a>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
/* SDMMC4 for EMMC */
mmc@700b0600 {
status = "disabled";
bus-width = <8>;
max-frequency = <200000000>;
cap-mmc-highspeed;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
mmc-hs400-1_8v;
non-removable;
vqmmc-supply = <&max77620_sd3>;
vmmc-supply = <&vdd_3v3>;
};
/* SDMMC3 Not Used */
mmc@700b0400 {
status = "disabled";
vqmmc-supply = <&max77620_sd3>;
vmmc-supply = <&vdd_3v3>;
};
/* SDMMC2 for Gamecard */
mmc@700b0200 {
status = "disabled";
bus-width = <8>;
max-frequency = <200000000>;
mmc-ddr-1_8v;
mmc-hs400-1_8v;
mmc-hs200-1_8v;
cap-mmc-highspeed;
cap-sd-highspeed;
non-removable;
vqmmc-supply = <&max77620_sd3>;
vmmc-supply = <&vdd_3v3>;
};
/* SDMMC1 for SD Card */
mmc@700b0000 {
status = "okay";
bus-width = <4>;
max-frequency = <200000000>;
cap-sd-highspeed;
sd-uhs-sdr12;
sd-uhs-sdr50;
sd-uhs-sdr104;
cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
vmmc-supply = <&en_vdd_sd>;
vqmmc-supply = <&max77620_ldo2>;
};
hda@70030000 {
status = "okay";
};
/* i2c1 @ 100000hz
1c: realtek 5639
18: rohm usb-pd
4c: ti temperature sensor
6b: ti charger
36: maxim fuel gauge
*/
i2c@7000c000 {
status = "okay";
clock-frequency = <100000>;
bq24193@6b {
compatible = "ti,bq24193";
reg = <0x6b>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(Z, 0) IRQ_TYPE_LEVEL_LOW>;
monitored-battery = <&fuel_gauge>;
#extcon-cells = <1>;
omit-battery-class;
battery_charger: charger {
regulator-name = "batt_regulator";
regulator-max-microamp = <4500000>;
};
usb0_vbus: usb-otg-vbus {
regulator-name = "vbus_regulator";
};
};
fuel_gauge: fuel-gauge@36 {
compatible = "maxim,max17050";
status = "okay";
reg = <0x36>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(Y, 0) IRQ_TYPE_NONE>;
/* Actual is 5000 but driver does not account for CGAIN */
/* And does not take into account Rsense and CGAIN for capacity */
maxim,rsns-microohm = <10000>;
maxim,over-heat-temp = <600>;
maxim,dead-volt = <3000>;
maxim,over-volt = <4208>; /* Actual: 4258 mV */
#thermal-sensor-cells = <0>;
};
rt5639: audio-codec@1c {
status = "okay";
compatible = "realtek,rt5639";
reg = <0x1c>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(BB, 4) IRQ_TYPE_EDGE_RISING>;
realtek,ldo1-en-gpios = <&gpio TEGRA_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
realtek,over-current-threshold-microamp = <600>;
realtek,over-current-scale-factor = <2>;
realtek,jack-detect-is-jd1;
};
/* PD Chip */
bm92t: bm92t@18 {
compatible = "rohm,bm92t";
reg = <0x18>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(K, 4) IRQ_TYPE_EDGE_RISING>;
#extcon-cells = <1>;
pd_bat_chg-supply = <&battery_charger>;
vbus-source-supply = <&v_vdd5v3>;
vbus-supply = <&usb0_vbus>;
rohm,dp-lanes = <2>;
rohm,dp-signal-toggle-on-resume;
/* Absolute max is 2.4A, constrained by BQ24193 ILIM */
rohm,pd-5v-current-limit-ma = <2000>;
rohm,pd-9v-current-limit-ma = <2000>;
rohm,pd-12v-current-limit-ma = <1500>;
rohm,pd-15v-current-limit-ma = <1200>;
port {
usb_con_ep: endpoint {
remote-endpoint = <&usb_port_0>;
};
};
};
tmp451: temperature-sensor@4c {
compatible = "ti,tmp451";
status = "okay";
reg = <0x4c>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(X, 4) IRQ_TYPE_EDGE_FALLING>;
vcc-supply = <&battery_reg>;
#thermal-sensor-cells = <1>;
};
};
/* i2c3 @ 400000hz
49: stm touchscreen controller
*/
i2c@7000c500 {
status = "okay";
clock-frequency = <400000>;
touchscreen@49 {
compatible = "stm,ftm4_fts";
status = "okay";
reg = <0x49>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(X, 1) IRQ_TYPE_LEVEL_LOW>;
vdd-tp-2v9-supply = <&max77620_ldo6>;
stm,vio-gpio = <&gpio TEGRA_GPIO(J, 7) GPIO_ACTIVE_HIGH>;
stm,irq_type = <0x2000>; /* IRQF_ONESHOT */
stm,regulator_avdd = "vdd-tp-2v9";
stm,max_coords = <1280 720>;
stm,max-real-coords = <1264 704>;
stm,edge-offset = <15 15>;
stm,delayed-open;
stm,delayed-open-time = <0>;
};
};
/* i2c2 @ 400000hz
29: rohm ambient light sensor
*/
i2c@7000c400 {
status = "okay";
clock-frequency = <400000>;
bh1730fvc: bh1730fvc@29 {
status = "disabled";
compatible = "rohm,bh1730fvc";
reg = <0x29>;
als-vid-supply = <&max77620_ldo6>;
als-vdd-supply = <&vdd_3v3>;
rohm,integration-cycle = <38>;
rohm,lux-multiplier = <3600>;
rohm,opt-win-coeff = < 500 5002 7502
754 2250 2000
1029 1999 1667
1373 884 583
1879 309 165>;
rohm,gain-coeff = < 2500 0
1600 7800
10 50000
0 1000>;
};
};
spi@7000da00 {
status = "disabled"; /* Disabled for Vali */
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
// spi-cs-setup-delay-ns = <2>;
// spi-cs-hold-delay-ns = <2>;
// spi-cs-inactive-delay-ns = <2>;
/*
* Model WHOAMI:
* LSM6DS3H 0x69, LSM6DSE 0x6A, LSM6DSO 0x6C, ICM40607 0x38.
*/
gyroscope: imu@0 {
reg = <0>;
status = "disabled";
compatible = "st,lsm6ds3h";
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <8000000>;
/* SPI Mode-3 */
spi-cpha;
spi-cpol;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(X, 2) IRQ_TYPE_LEVEL_HIGH>;
vdd-supply = <&battery_reg>;
vddio-supply = <&battery_reg>;
st,drdy-int-pin = <2>;
nvidia,rx-clk-tap-delay = <0x1f>;
nvidia,tx-clk-tap-delay = <0x0>;
mount-matrix =
"1", "0", "0", /* X: x */
"0", "1", "0", /* Y: y */
"0", "0", "1"; /* Z: z */
};
};
gpio-keys {
compatible = "gpio-keys";
key-volume-down {
label = "Volume Down";
gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_VOLUMEDOWN>;
debounce-interval = <10>;
};
key-volume-up {
label = "Volume Up";
gpios = <&gpio TEGRA_GPIO(X, 6) GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_VOLUMEUP>;
debounce-interval = <10>;
};
};
gpio@6000d000 {
boot-default-output-high {
gpio-hog;
output-high;
gpios = <TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>; /* Wi-Fi Reset. Powered on by default. */
line-name = "boot-default-output-high";
};
};
pwm@7000a000 {
status = "okay";
#pwm-cells = <2>;
};
fan: pwm-fan {
compatible = "pwm-fan";
cooling-min-state = <0>;
cooling-max-state = <5>;
#cooling-cells = <2>;
pwms = <&pwm 1 33333>;
fan-supply = <&v_vdd50_a>;
enable-gpios = <&gpio TEGRA_GPIO(A, 5) GPIO_ACTIVE_HIGH>;
/* cooling level (0, 1, 2, 3, 4, 5) - pwm inverted */
cooling-levels = <255 204 153 102 51 0>;
};
sound {
status = "okay";
compatible = "nvidia,tegra-audio-rt5640-tx1",
"nvidia,tegra-audio-rt5640";
nvidia,model = "Nintendo Switch";
nvidia,audio-codec = <&rt5639>;
nvidia,i2s-controller = <&tegra_i2s1>;
// nvidia,hp-det-gpios = <&gpio 143 0>;
clocks = <&tegra_car TEGRA210_CLK_PLL_A>,
<&tegra_car TEGRA210_CLK_PLL_A_OUT0>,
<&tegra_car TEGRA210_CLK_CLK_M>;
clock-names = "pll_a", "plla_out0", "mclk";
assigned-clocks = <&tegra_car TEGRA210_CLK_PLL_A>,
<&tegra_car TEGRA210_CLK_PLL_A_OUT0>,
<&tegra_car TEGRA210_CLK_D_AUDIO>,
<&tegra_car TEGRA210_CLK_EXTERN1>;
assigned-clock-rates = <368640000>, <36864000>,
<36864000>, <12288000>;
nvidia,audio-routing =
"Headphones", "HPOL",
"Headphones", "HPOR",
"Speakers", "SPORP",
"Speakers", "SPORN",
"Speakers", "SPOLP",
"Speakers", "SPOLN",
"IN1P", "Mic Jack",
"IN1P", "Mic Jack";
};
thermal-zones {
cpu {
polling-delay-passive = <250>;
polling-delay = <500>;
status = "okay";
/* Based on Console profile SoC: 95% (100% at Handheld) */
coefficients = <95 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
thermal-sensors = <&tmp451 1>;
trips {
cpu_critical: cpu-critical {
temperature = <102500>;
hysteresis = <0>;
type = "critical";
};
cpu_heavy: cpu-heavy {
temperature = <98500>;
hysteresis = <1000>;
type = "hot";
};
cpu_throttle: cpu-throttle {
temperature = <89000>;
hysteresis = <2000>;
type = "passive";
};
cpu_cap_trip1: cpu-cap-trip1 {
temperature = <58000>;
hysteresis = <2000>;
type = "active";
};
cpu_floor_trip1: cpu-floor-trip1 {
temperature = <53000>;
hysteresis = <2000>;
type = "active";
};
cpu_cap_trip0: cpu-cap-trip0 {
temperature = <48000>;
hysteresis = <2000>;
type = "active";
};
cpu_floor_trip0: cpu-floor-trip0 {
temperature = <43000>;
hysteresis = <2000>;
type = "active";
};
};
cooling-maps {
map0 {
cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
trip = <&cpu_critical>;
};
map1 {
cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
trip = <&cpu_heavy>;
};
map2 {
cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
trip = <&cpu_throttle>;
};
map3 {
cooling-device = <&fan 1 1>;
trip = <&cpu_cap_trip1>;
};
map4 {
cooling-device = <&fan 2 2>;
trip = <&cpu_floor_trip1>;
};
map5 {
cooling-device = <&fan 3 3>;
trip = <&cpu_cap_trip0>;
};
map6 {
cooling-device = <&fan 4 4>;
trip = <&cpu_floor_trip0>;
};
};
};
gpu {
polling-delay-passive = <250>;
polling-delay = <500>;
status = "okay";
thermal-sensors = <&tmp451 1>;
trips {
gpu_critical: gpu-critical {
temperature = <103000>;
hysteresis = <0>;
type = "critical";
};
gpu_heavy: gpu-heavy {
temperature = <100000>;
hysteresis = <1000>;
type = "hot";
};
gpu_throttle: gpu-throttle {
temperature = <90500>;
hysteresis = <0>;
type = "passive";
};
};
cooling-maps {
map0 {
trip = <&gpu_critical>;
cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
map1 {
trip = <&gpu_heavy>;
cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
map2 {
trip = <&gpu_throttle>;
cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
pmic {
status = "okay";
polling-delay-passive = <250>;
polling-delay = <500>;
thermal-sensors = <&max77620>;
trips {
pmic_die_warn_temp_thresh: hot-die {
temperature = <120000>;
type = "hot";
hysteresis = <0>;
};
pmic_die_cirt_temp_thresh: critical-die {
temperature = <140000>;
type = "critical";
hysteresis = <0>;
};
};
cooling-maps {
map0 {
trip = <&pmic_die_warn_temp_thresh>;
cooling-device = <&throttle_heavy 1 1>;
contribution = <100>;
};
};
};
cpu_vreg {
status = "okay";
polling-delay-passive = <250>;
polling-delay = <500>;
thermal-sensors = <&cpu_max_reg>;
trips {
cpu_vreg_die_warn_temp_thresh: hot-die {
temperature = <120000>;
type = "hot";
hysteresis = <0>;
};
};
cooling-maps {
map0 {
trip = <&cpu_vreg_die_warn_temp_thresh>;
cooling-device = <&throttle_heavy 1 1>;
contribution = <100>;
};
};
};
gpu_vreg {
status = "okay";
polling-delay-passive = <250>;
polling-delay = <500>;
thermal-sensors = <&gpu_max_reg>;
trips {
gpu_vreg_die_warn_temp_thresh: hot-die {
temperature = <120000>;
type = "hot";
hysteresis = <0>;
};
};
cooling-maps {
/*
* There are currently no cooling maps,
* because there are no cooling devices.
*/
};
};
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -2263,6 +2263,25 @@
};
};
core_dvfs_floor: core_dvfs_cdev_floor {
compatible = "nvidia,tegra-core-cdev-action";
cdev-type = "CORE-floor";
#cooling-cells = <2>; /* min followed by max */
};
core_dvfs_cap: core_dvfs_cdev_cap {
compatible = "nvidia,tegra-core-cdev-action";
cdev-type = "CORE-cap";
#cooling-cells = <2>; /* min followed by max */
clocks = <&tegra_car TEGRA210_CLK_CAP_VCORE_C2BUS>,
<&tegra_car TEGRA210_CLK_CAP_VCORE_C3BUS>,
<&tegra_car TEGRA210_CLK_CAP_VCORE_SCLK>,
<&tegra_car TEGRA210_CLK_CAP_VCORE_HOST1X>,
<&tegra_car TEGRA210_CLK_CAP_VCORE_ABUS>;
clock-names = "c2bus_cap", "c3bus_cap", "sclk_cap",
"host1x_cap", "adsp_cap";
};
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13

View File

@@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "tegra210b01-nx.dtsi"
/ {
model = "Nintendo Switch (OLED model)";
compatible = "nvidia,fric", "nintendo,aula", "nintendo,nx", "nvidia,tegra210b01";
};

View File

@@ -0,0 +1,432 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/mfd/max77620.h>
#include "tegra210b01.dtsi"
/ {
aliases {
serial0 = &uarta;
};
chosen {
stdout-path = "serial0:115200n8";
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0xc0000000>;
};
serial@70006000 {
/delete-property/ dmas;
/delete-property/ dma-names;
status = "okay";
};
pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <0>;
nvidia,cpu-pwr-good-time = <0>;
nvidia,cpu-pwr-off-time = <0>;
nvidia,core-pwr-good-time = <13100 7800>;
nvidia,core-pwr-off-time = <44160>;
nvidia,core-power-req-active-high;
nvidia,sys-clock-req-active-high;
status = "okay";
};
mmc@700b0600 {
bus-width = <8>;
non-removable;
status = "okay";
};
clk32k_in: clock-32k {
compatible = "fixed-clock";
clock-frequency = <32768>;
#clock-cells = <0>;
};
cpus {
cpu@0 {
enable-method = "psci";
};
cpu@1 {
enable-method = "psci";
};
cpu@2 {
enable-method = "psci";
};
cpu@3 {
enable-method = "psci";
};
};
psci {
compatible = "arm,psci-1.0";
method = "smc";
};
i2c@7000d000 {
status = "okay";
clock-frequency = <400000>;
pmic_a: pmic@33 {
compatible = "maxim,max77812-regulator";
reg = <0x33>;
maxim,soft-start-slew-rate = <5000>;
maxim,shutdown-slew-rate = <5000>;
maxim,ramp-up-slew-rate = <5000>;
maxim,ramp-down-slew-rate = <5000>;
status = "okay";
/* interrupt-parent = <&gpio>; */
/* interrupts = <TEGRA_GPIO(K, 6) IRQ_TYPE_NONE>; */
regulators {
gpu_max_reg: m1vout {
regulator-name = "vdd-gpu";
regulator-min-microvolt = <250000>;
regulator-max-microvolt = <1525000>;
/* regulator-max-microamp = <10000000>; */ /* 0x33 cfg */
/* regulator-max-microamp = <15000000>; */ /* 0x31 cfg */
regulator-init-microvolt = <800000>;
regulator-ramp-delay = <5000>;
regulator-enable-ramp-delay = <5000>;
regulator-disable-ramp-delay = <5000>;
maxim,peak-current-limit-ua = <7200000>;
};
m2vout {
regulator-name = "vdd-mvout2";
regulator-min-microvolt = <250000>;
regulator-max-microvolt = <1525000>;
regulator-ramp-delay = <5000>;
regulator-enable-ramp-delay = <5000>;
regulator-disable-ramp-delay = <5000>;
maxim,peak-current-limit-ua = <7200000>;
};
ram_max_reg: m3vout {
status = "okay";
regulator-name = "vddio-ddr";
regulator-min-microvolt = <550000>; /* Set min lpddr4x normally allowed */
regulator-max-microvolt = <650000>; /* Set max lpddr4x normally allowed */
/* regulator-max-microamp = <5000000>; */
regulator-always-on;
regulator-boot-on;
/* regulator-init-microvolt = <600000>; */ /* Controlled by bootloader */
regulator-ramp-delay = <5000>;
regulator-enable-ramp-delay = <5000>;
regulator-disable-ramp-delay = <5000>;
maxim,peak-current-limit-ua = <7200000>;
};
cpu_max_reg: m4vout {
regulator-name = "vdd-cpu";
regulator-min-microvolt = <250000>;
regulator-max-microvolt = <1525000>;
/* regulator-max-microamp = <5000000>; */
regulator-always-on;
regulator-boot-on;
regulator-init-microvolt = <1000000>;
regulator-ramp-delay = <5000>;
regulator-enable-ramp-delay = <5000>;
regulator-disable-ramp-delay = <5000>;
maxim,peak-current-limit-ua = <7200000>;
};
};
};
pmic_b: pmic@3c {
compatible = "maxim,max77620";
reg = <0x3c>;
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <2>;
interrupt-controller;
gpio-controller;
#gpio-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&max77620_default>;
fps {
#address-cells = <1>;
#size-cells = <0>;
fps0 {
reg = <0>;
maxim,shutdown-fps-time-period-us = <5120>;
maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
};
fps1 {
reg = <1>;
maxim,shutdown-fps-time-period-us = <5120>;
maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
maxim,device-state-on-disabled-event = <MAX77620_FPS_INACTIVE_STATE_SLEEP>;
};
fps2 {
reg = <2>;
maxim,shutdown-fps-time-period-us = <5120>;
maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
};
};
// hog-0 {
// gpio-hog;
// output-high;
// gpios = <2 GPIO_ACTIVE_HIGH>,
// <7 GPIO_ACTIVE_HIGH>;
// };
max77620_default: pinmux {
gpio0 {
pins = "gpio0";
function = "gpio";
};
gpio1 {
pins = "gpio1";
function = "fps-out";
drive-open-drain = <1>;
maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
maxim,active-fps-power-up-slot = <5>;
maxim,active-fps-power-down-slot = <0>;
};
gpio2 {
pins = "gpio2";
function = "fps-out";
drive-open-drain = <1>;
maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
maxim,active-fps-power-up-slot = <6>;
maxim,active-fps-power-down-slot = <0>;
};
gpio3 {
pins = "gpio3";
function = "fps-out";
drive-open-drain = <1>;
maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
maxim,active-fps-power-up-slot = <3>;
maxim,active-fps-power-down-slot = <0>;
};
gpio4 {
pins = "gpio4";
function = "32k-out1";
};
gpio5_6_7 {
pins = "gpio5", "gpio6", "gpio7";
function = "gpio";
drive-open-drain = <1>;
};
};
regulators {
in-ldo0-1-supply = <&max77620_sd2>;
in-ldo7-8-supply = <&max77620_sd2>;
max77620_sd0: sd0 {
regulator-name = "vdd-core";
regulator-min-microvolt = <625000>;
regulator-max-microvolt = <1400000>;
regulator-boot-on;
regulator-always-on;
maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
maxim,active-fps-power-up-slot = <1>;
maxim,active-fps-power-down-slot = <7>;
// regulator-initial-mode = <REGULATOR_MODE_NORMAL>;
regulator-enable-ramp-delay = <50>;
regulator-disable-ramp-delay = <4080>;
maxim,ramp-rate-setting = <27500>;
regulator-ramp-delay = <27500>;
};
max77620_sd1: sd1 {
regulator-name = "vdd-ddr";
regulator-min-microvolt = <1050000>;
regulator-max-microvolt = <1175000>;
regulator-always-on;
regulator-boot-on;
/* regulator-init-microvolt = <1100000>; */ /* Controlled by bootloader */
// regulator-initial-mode = <REGULATOR_MODE_NORMAL>;
maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
maxim,active-fps-power-up-slot = <5>;
maxim,active-fps-power-down-slot = <2>;
regulator-enable-ramp-delay = <60>;
regulator-disable-ramp-delay = <145800>;
maxim,ramp-rate-setting = <27500>;
regulator-ramp-delay = <27500>;
};
max77620_sd2: sd2 {
regulator-name = "vdd-pre-reg";
regulator-min-microvolt = <1325000>;
regulator-max-microvolt = <1325000>;
regulator-always-on;
regulator-boot-on;
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <40>;
regulator-disable-ramp-delay = <20000>;
maxim,ramp-rate-setting = <27500>;
regulator-ramp-delay = <27500>;
};
max77620_sd3: sd3 {
regulator-name = "vdd-1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
maxim,active-fps-power-up-slot = <2>;
maxim,active-fps-power-down-slot = <4>;
// regulator-initial-mode = <REGULATOR_MODE_NORMAL>;
regulator-enable-ramp-delay = <50>;
regulator-disable-ramp-delay = <118000>;
maxim,ramp-rate-setting = <27500>;
regulator-ramp-delay = <27500>;
};
max77620_ldo0: ldo0 {
regulator-name = "avdd-sys";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-boot-on; /* Must be set for seamless display */
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <50>;
regulator-disable-ramp-delay = <4000>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
max77620_ldo1: ldo1 {
regulator-name = "vdd-pex";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <50>;
regulator-disable-ramp-delay = <7000>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
max77620_ldo2: ldo2 {
regulator-name = "vddio-sdmmc1";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <100>;
regulator-disable-ramp-delay = <6000>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
max77620_ldo3: ldo3 {
regulator-name = "vdd-gc-3v1";
regulator-min-microvolt = <3100000>;
regulator-max-microvolt = <3100000>;
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <100>;
regulator-disable-ramp-delay = <3000>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
max77620_ldo4: ldo4 {
regulator-name = "vdd-rtc";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <800000>;
regulator-always-on;
regulator-boot-on;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <7>;
maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
regulator-enable-ramp-delay = <50>;
regulator-disable-ramp-delay = <610>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
/* GC Card Vddio */
max77620_ldo5: ldo5 {
regulator-name = "vdd-gc-1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <70>;
regulator-disable-ramp-delay = <3000>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
/* Touch Panel, ALS. Powers LDO 1V8. */
max77620_ldo6: ldo6 {
regulator-name = "vdd-tp-2v9";
regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <2900000>;
regulator-boot-on; /* Decrease por time for Touch Panel. */
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <100>;
regulator-disable-ramp-delay = <3000>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
/* Not used on T210B01 */
max77620_ldo7: ldo7 {
regulator-name = "vdd-gen-pll-edp";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>; /* 3100000 */
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <50>;
regulator-disable-ramp-delay = <2768>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
/* Odin/Modin/Fric: DP. */
/* Vali: Powers LDO 2V8 for Sio VDD
* Powers LDO 1V8 for I2C1 VDDQ and ALC5639.
*/
max77620_ldo8: ldo8 {
regulator-name = "vdd-hdmi-dp";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
maxim,active-fps-power-up-slot = <0>;
maxim,active-fps-power-down-slot = <0>;
regulator-enable-ramp-delay = <50>;
regulator-disable-ramp-delay = <4000>;
maxim,ramp-rate-setting = <50000>;
regulator-ramp-delay = <50000>;
};
};
};
};
};

View File

@@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "tegra210b01-nx.dtsi"
/ {
model = "Nintendo Switch (2019)";
compatible = "nvidia,modin", "nvidia,odin", "nintendo,iowa", "nintendo,nx", "nvidia,tegra210b01";
};

View File

@@ -0,0 +1,67 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "tegra210b01-nx.dtsi"
/ {
model = "Nintendo Switch Lite";
compatible = "nvidia,vali", "nintendo,hoag", "nintendo,nx", "nvidia,tegra210b01";
/* Joycon/Fan power (usb) */
v_vdd50_b: v-vdd50-b {
status = "disabled"; /* Only enabled on Odin/Modin */
};
en_vdd_jcl_chgr: left-joycon-charger {
status = "disabled"; /* Only enabled on Odin/Modin/Fric */
};
en_vdd_jcr_chgr: right-joycon-charger {
status = "disabled"; /* Only enabled on Odin/Modin/Fric */
};
spi@7000da00 {
status = "disabled"; /* Disabled for Vali since Sio uses it */
};
/* Right Joycon */
serial@70006040 {
status = "disabled";
joyconr {
status = "disabled";
};
};
/* Left Joycon / Sio */
serial@70006200 {
status = "okay";
/delete-property/ nvidia,invert-txd;
/delete-property/ nvidia,invert-rts;
joyconl {
status = "disabled";
};
sio {
status = "okay";
};
};
i2c@7000d000 {
pmic_b: pmic@3c {
regulators {
/* Vali: Powers LDO 2V8 for Sio VDD
* Powers LDO 1V8 for I2C1 VDDQ and ALC5639.
*/
ldo8 {
regulator-name = "vdd-i2c1";
regulator-max-microvolt = <2800000>;
regulator-always-on;
regulator-boot-on;
};
};
};
};
};

View File

@@ -7,13 +7,19 @@
host1x@50000000 {
/delete-node/ sor@54540000;
/delete-node/ dpaux@545c0000;
/delete-node/ vi@54080000;
/delete-node/ i2c@546c0000;
dc@54200000 {
nvidia,outputs = <&dsia &dsib &sor1>;
/delete-property/ interconnects;
/delete-property/ interconnect-names;
};
dc@54240000 {
nvidia,outputs = <&dsia &dsib &sor1>;
/delete-property/ interconnects;
/delete-property/ interconnect-names;
};
};
@@ -27,12 +33,80 @@
/delete-property/ pinctrl-names;
};
emc: external-memory-controller@7001b000 {
compatible = "nvidia,tegra210b01-emc";
clocks = <&bpmp 0>;
clock-names = "emc";
nvidia,bpmp = <&bpmp>;
/delete-property/ operating-points-v2;
};
actmon@6000c800 {
// clocks = <&tegra_car TEGRA210_CLK_ACTMON>,
// <&bpmp 0>;
status = "disabled";
};
mmc@700b0600 {
nvidia,default-tap = <9>;
nvidia,default-trim = <13>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
<&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
};
mmc@700b0400 {
nvidia,default-tap = <11>;
nvidia,default-trim = <18>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC3>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
};
mmc@700b0200 {
nvidia,default-tap = <8>;
nvidia,default-trim = <13>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC2>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
};
mmc@700b0000 {
nvidia,default-tap = <11>;
nvidia,default-trim = <14>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>,
<&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
<&tegra_car TEGRA210_CLK_PLL_C4_OUT2>,
<&tegra_car TEGRA210_CLK_PLL_C4>;
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
};
pcie@1003000 {
compatible = "nvidia,tegra210b01-pcie";
};
/* Tegra210B01 has MBIST patched and is missing VI unit */
pmc@7000e400 {
compatible = "nvidia,tegra210b01-pmc";
powergates {
/delete-node/ venc;
};
};
bpmp@70016000 {
status = "okay";
#clock-cells = <1>;
};
usb@70090000 {
@@ -43,6 +117,41 @@
compatible = "nvidia,tegra210b01-xusb-padctl";
};
pinmux@700008d4 {
status = "okay";
sdmmc1_drv_code_1_8V: sdmmc1_drv_code {
sdmmc1 {
nvidia,pins = "drive_sdmmc1";
nvidia,pull-down-strength = <8>;
nvidia,pull-up-strength = <8>;
};
};
sdmmc1_default_drv_code_3_3V: sdmmc1_default_drv_code {
sdmmc1 {
nvidia,pins = "drive_sdmmc1";
nvidia,pull-down-strength = <8>;
nvidia,pull-up-strength = <8>;
};
};
sdmmc3_drv_code_1_8V: sdmmc3_drv_code {
sdmmc3 {
nvidia,pins = "drive_sdmmc3";
nvidia,pull-down-strength = <8>;
nvidia,pull-up-strength = <8>;
};
};
sdmmc3_default_drv_code_3_3V: sdmmc3_default_drv_code {
sdmmc3 {
nvidia,pins = "drive_sdmmc3";
nvidia,pull-down-strength = <8>;
nvidia,pull-up-strength = <8>;
};
};
};
usb@700d0000 {
compatible = "nvidia,tegra210b01-xudc";
};

View File

@@ -777,6 +777,7 @@ CONFIG_REGULATOR_HI6421V530=y
CONFIG_REGULATOR_HI655X=y
CONFIG_REGULATOR_LP873X=m
CONFIG_REGULATOR_MAX77620=y
CONFIG_REGULATOR_MAX77812=y
CONFIG_REGULATOR_MAX8973=y
CONFIG_REGULATOR_MAX20411=m
CONFIG_REGULATOR_MP8859=y

View File

@@ -2554,6 +2554,13 @@ static void clk_change_rate(struct clk_core *core)
if (core->ops->post_rate_change)
core->ops->post_rate_change(core->hw, old_rate, core->rate);
/*
* Allow children to be aware that next set rate operation is triggered
* by downward rate propagation, rather than direct set rate on itself.
*/
if (core->notifier_count)
__clk_notify(core, PRE_SUBTREE_CHANGE, old_rate, core->rate);
/*
* Use safe iteration, as change_rate can actually swap parents
* for certain clock types.
@@ -2569,6 +2576,9 @@ static void clk_change_rate(struct clk_core *core)
if (core->new_child)
clk_change_rate(core->new_child);
if (core->notifier_count)
__clk_notify(core, POST_SUBTREE_CHANGE, old_rate, core->rate);
clk_pm_runtime_put(core);
}
@@ -2949,6 +2959,7 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
int ret = 0;
int p_index = 0;
unsigned long p_rate = 0;
unsigned long old_p_rate = 0;
lockdep_assert_held(&prepare_lock);
@@ -2991,13 +3002,23 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
if (ret & NOTIFY_STOP_MASK)
goto runtime_put;
/* do the re-parent */
/* propagate PRE_PARENT_CHANGE notifications */
if (core->parent)
old_p_rate = core->parent->rate;
ret = __clk_notify(core, PRE_PARENT_CHANGE, old_p_rate, p_rate);
/* do the re-parent if no objections */
if (!(ret & NOTIFY_STOP_MASK))
ret = __clk_set_parent(core, parent, p_index);
/* propagate rate an accuracy recalculation accordingly */
if (ret) {
__clk_notify(core, ABORT_PARENT_CHANGE, old_p_rate, p_rate);
__clk_recalc_rates(core, true, ABORT_RATE_CHANGE);
} else {
__clk_notify(core, POST_PARENT_CHANGE, old_p_rate, p_rate);
__clk_recalc_rates(core, true, POST_RATE_CHANGE);
__clk_recalc_accuracies(core);
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,36 +13,64 @@
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/types.h>
#include <soc/tegra/tegra-dfll.h>
#include "cvb.h"
struct thermal_tv;
/**
* struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver
* @dev: struct device * that holds the OPP table for the DFLL
* @max_freq: maximum frequency supported on this SoC
* @cvb: CPU frequency table for this SoC
* @alignment: parameters of the regulator step and offset
* @init_clock_trimmers: callback to initialize clock trimmers
* @set_clock_trimmers_high: callback to tune clock trimmers for high voltage
* @set_clock_trimmers_low: callback to tune clock trimmers for low voltage
* @tune0_low: DFLL tuning register 0 (low voltage range)
* @tune0_high: DFLL tuning register 0 (high voltage range)
* @tune1: DFLL tuning register 1
* @set_clock_trimmers_high: fn ptr to tune clock trimmers for high voltage
* @set_clock_trimmers_low: fn ptr to tune clock trimmers for low voltage
* @thermal_floor_table: table mapping a given temperature to a minimum voltage
* @thermal_cap_table: table mapping a given temperature to a maximum voltage
* @thermal_floor_table_size: size of thermal_floor_table
* @thermal_cap_table_size: size of thermal_cap_table
*/
struct tegra_dfll_soc_data {
struct device *dev;
unsigned long max_freq;
const struct cvb_table *cvb;
struct rail_alignment alignment;
unsigned int min_millivolts;
unsigned int tune_high_min_millivolts;
u32 tune0_low;
u32 tune0_high;
u32 tune1_low;
u32 tune1_high;
unsigned int tune_high_margin_millivolts;
void (*init_clock_trimmers)(void);
void (*set_clock_trimmers_high)(void);
void (*set_clock_trimmers_low)(void);
const struct thermal_tv *thermal_floor_table;
const struct thermal_tv *thermal_cap_table;
unsigned int thermal_floor_table_size;
unsigned int thermal_cap_table_size;
};
/*
* These thermal boundaries are not set in thermal zone as trip-points, but
* must be below/above all other actually set DFLL thermal trip-points.
*/
#define DFLL_THERMAL_CAP_NOCAP 0
#define DFLL_THERMAL_FLOOR_NOFLOOR 125000
int tegra_dfll_register(struct platform_device *pdev,
struct tegra_dfll_soc_data *soc);
struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev);
void tegra_dfll_suspend(struct platform_device *pdev);
void tegra_dfll_resume(struct platform_device *pdev, bool on_dfll);
int tegra_dfll_resume_tuning(struct device *dev);
int tegra_dfll_runtime_suspend(struct device *dev);
int tegra_dfll_runtime_resume(struct device *dev);
int tegra_dfll_suspend(struct device *dev);
int tegra_dfll_resume(struct device *dev);
#endif /* __DRIVERS_CLK_TEGRA_CLK_DFLL_H */

View File

@@ -17,15 +17,18 @@
#include <linux/regulator/consumer.h>
#include <soc/tegra/fuse.h>
#include <dt-bindings/thermal/tegra210-dfll-trips.h>
#include <dt-bindings/thermal/tegra210b01-trips.h>
#include "clk.h"
#include "clk-dfll.h"
#include "cvb.h"
struct dfll_fcpu_data {
const unsigned long *cpu_max_freq_table;
unsigned int cpu_max_freq_table_size;
const struct cvb_table *cpu_cvb_tables;
unsigned int cpu_cvb_tables_size;
const struct thermal_table *cpu_thermal_table;
};
/* Maximum CPU frequency, indexed by CPU speedo id */
@@ -42,6 +45,9 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
.process_id = -1,
.min_millivolts = 900,
.max_millivolts = 1260,
.alignment = {
.step_uv = 10000, /* 10mV */
},
.speedo_scale = 100,
.voltage_scale = 1000,
.entries = {
@@ -74,7 +80,7 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0x005020ff,
.tune0_high = 0x005040ff,
.tune1 = 0x00000060,
.tune1_low = 0x00000060,
}
},
};
@@ -97,142 +103,142 @@ static const unsigned long tegra210_cpu_max_freq_table[] = {
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
{ 204000000UL, { 1007452, -23865, 370 } }, \
{ 306000000UL, { 1052709, -24875, 370 } }, \
{ 408000000UL, { 1099069, -25895, 370 } }, \
{ 510000000UL, { 1146534, -26905, 370 } }, \
{ 612000000UL, { 1195102, -27915, 370 } }, \
{ 714000000UL, { 1244773, -28925, 370 } }, \
{ 816000000UL, { 1295549, -29935, 370 } }, \
{ 918000000UL, { 1347428, -30955, 370 } }, \
{ 1020000000UL, { 1400411, -31965, 370 } }, \
{ 1122000000UL, { 1454497, -32975, 370 } }, \
{ 1224000000UL, { 1509687, -33985, 370 } }, \
{ 1326000000UL, { 1565981, -35005, 370 } }, \
{ 1428000000UL, { 1623379, -36015, 370 } }, \
{ 1530000000UL, { 1681880, -37025, 370 } }, \
{ 1632000000UL, { 1741485, -38035, 370 } }, \
{ 1734000000UL, { 1802194, -39055, 370 } }, \
{ 1836000000UL, { 1864006, -40065, 370 } }, \
{ 1912500000UL, { 1910780, -40815, 370 } }, \
{ 2014500000UL, { 1227000, 0, 0 } }, \
{ 2218500000UL, { 1227000, 0, 0 } }, \
{ 0UL, { 0, 0, 0 } }, \
{204000000UL, {1007452, -23865, 370} }, \
{306000000UL, {1052709, -24875, 370} }, \
{408000000UL, {1099069, -25895, 370} }, \
{510000000UL, {1146534, -26905, 370} }, \
{612000000UL, {1195102, -27915, 370} }, \
{714000000UL, {1244773, -28925, 370} }, \
{816000000UL, {1295549, -29935, 370} }, \
{918000000UL, {1347428, -30955, 370} }, \
{1020000000UL, {1400411, -31965, 370} }, \
{1122000000UL, {1454497, -32975, 370} }, \
{1224000000UL, {1509687, -33985, 370} }, \
{1326000000UL, {1565981, -35005, 370} }, \
{1428000000UL, {1623379, -36015, 370} }, \
{1530000000UL, {1681880, -37025, 370} }, \
{1632000000UL, {1741485, -38035, 370} }, \
{1734000000UL, {1802194, -39055, 370} }, \
{1836000000UL, {1864006, -40065, 370} }, \
{1912500000UL, {1910780, -40815, 370} }, \
{2014500000UL, {1227000, 0, 0} }, \
{2218500000UL, {1227000, 0, 0} }, \
{0, { 0, 0, 0} }, \
}
#define CPU_CVB_TABLE_XA \
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
{ 204000000UL, { 1250024, -39785, 565 } }, \
{ 306000000UL, { 1297556, -41145, 565 } }, \
{ 408000000UL, { 1346718, -42505, 565 } }, \
{ 510000000UL, { 1397511, -43855, 565 } }, \
{ 612000000UL, { 1449933, -45215, 565 } }, \
{ 714000000UL, { 1503986, -46575, 565 } }, \
{ 816000000UL, { 1559669, -47935, 565 } }, \
{ 918000000UL, { 1616982, -49295, 565 } }, \
{ 1020000000UL, { 1675926, -50645, 565 } }, \
{ 1122000000UL, { 1736500, -52005, 565 } }, \
{ 1224000000UL, { 1798704, -53365, 565 } }, \
{ 1326000000UL, { 1862538, -54725, 565 } }, \
{ 1428000000UL, { 1928003, -56085, 565 } }, \
{ 1530000000UL, { 1995097, -57435, 565 } }, \
{ 1606500000UL, { 2046149, -58445, 565 } }, \
{ 1632000000UL, { 2063822, -58795, 565 } }, \
{ 0UL, { 0, 0, 0 } }, \
{204000000UL, {1250024, -39785, 565} }, \
{306000000UL, {1297556, -41145, 565} }, \
{408000000UL, {1346718, -42505, 565} }, \
{510000000UL, {1397511, -43855, 565} }, \
{612000000UL, {1449933, -45215, 565} }, \
{714000000UL, {1503986, -46575, 565} }, \
{816000000UL, {1559669, -47935, 565} }, \
{918000000UL, {1616982, -49295, 565} }, \
{1020000000UL, {1675926, -50645, 565} }, \
{1122000000UL, {1736500, -52005, 565} }, \
{1224000000UL, {1798704, -53365, 565} }, \
{1326000000UL, {1862538, -54725, 565} }, \
{1428000000UL, {1928003, -56085, 565} }, \
{1530000000UL, {1995097, -57435, 565} }, \
{1606500000UL, {2046149, -58445, 565} }, \
{1632000000UL, {2063822, -58795, 565} }, \
{0, { 0, 0, 0} }, \
}
#define CPU_CVB_TABLE_EUCM1 \
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
{ 204000000UL, { 734429, 0, 0 } }, \
{ 306000000UL, { 768191, 0, 0 } }, \
{ 408000000UL, { 801953, 0, 0 } }, \
{ 510000000UL, { 835715, 0, 0 } }, \
{ 612000000UL, { 869477, 0, 0 } }, \
{ 714000000UL, { 903239, 0, 0 } }, \
{ 816000000UL, { 937001, 0, 0 } }, \
{ 918000000UL, { 970763, 0, 0 } }, \
{ 1020000000UL, { 1004525, 0, 0 } }, \
{ 1122000000UL, { 1038287, 0, 0 } }, \
{ 1224000000UL, { 1072049, 0, 0 } }, \
{ 1326000000UL, { 1105811, 0, 0 } }, \
{ 1428000000UL, { 1130000, 0, 0 } }, \
{ 1555500000UL, { 1130000, 0, 0 } }, \
{ 1632000000UL, { 1170000, 0, 0 } }, \
{ 1734000000UL, { 1227500, 0, 0 } }, \
{ 0UL, { 0, 0, 0 } }, \
{204000000UL, {734429, 0, 0} }, \
{306000000UL, {768191, 0, 0} }, \
{408000000UL, {801953, 0, 0} }, \
{510000000UL, {835715, 0, 0} }, \
{612000000UL, {869477, 0, 0} }, \
{714000000UL, {903239, 0, 0} }, \
{816000000UL, {937001, 0, 0} }, \
{918000000UL, {970763, 0, 0} }, \
{1020000000UL, {1004525, 0, 0} }, \
{1122000000UL, {1038287, 0, 0} }, \
{1224000000UL, {1072049, 0, 0} }, \
{1326000000UL, {1105811, 0, 0} }, \
{1428000000UL, {1130000, 0, 0} }, \
{1555500000UL, {1130000, 0, 0} }, \
{1632000000UL, {1170000, 0, 0} }, \
{1734000000UL, {1227500, 0, 0} }, \
{0, { 0, 0, 0} }, \
}
#define CPU_CVB_TABLE_EUCM2 \
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
{ 204000000UL, { 742283, 0, 0 } }, \
{ 306000000UL, { 776249, 0, 0 } }, \
{ 408000000UL, { 810215, 0, 0 } }, \
{ 510000000UL, { 844181, 0, 0 } }, \
{ 612000000UL, { 878147, 0, 0 } }, \
{ 714000000UL, { 912113, 0, 0 } }, \
{ 816000000UL, { 946079, 0, 0 } }, \
{ 918000000UL, { 980045, 0, 0 } }, \
{ 1020000000UL, { 1014011, 0, 0 } }, \
{ 1122000000UL, { 1047977, 0, 0 } }, \
{ 1224000000UL, { 1081943, 0, 0 } }, \
{ 1326000000UL, { 1090000, 0, 0 } }, \
{ 1479000000UL, { 1090000, 0, 0 } }, \
{ 1555500000UL, { 1162000, 0, 0 } }, \
{ 1683000000UL, { 1195000, 0, 0 } }, \
{ 0UL, { 0, 0, 0 } }, \
{204000000UL, {742283, 0, 0} }, \
{306000000UL, {776249, 0, 0} }, \
{408000000UL, {810215, 0, 0} }, \
{510000000UL, {844181, 0, 0} }, \
{612000000UL, {878147, 0, 0} }, \
{714000000UL, {912113, 0, 0} }, \
{816000000UL, {946079, 0, 0} }, \
{918000000UL, {980045, 0, 0} }, \
{1020000000UL, {1014011, 0, 0} }, \
{1122000000UL, {1047977, 0, 0} }, \
{1224000000UL, {1081943, 0, 0} }, \
{1326000000UL, {1090000, 0, 0} }, \
{1479000000UL, {1090000, 0, 0} }, \
{1555500000UL, {1162000, 0, 0} }, \
{1683000000UL, {1195000, 0, 0} }, \
{0, { 0, 0, 0} }, \
}
#define CPU_CVB_TABLE_EUCM2_JOINT_RAIL \
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
{ 204000000UL, { 742283, 0, 0 } }, \
{ 306000000UL, { 776249, 0, 0 } }, \
{ 408000000UL, { 810215, 0, 0 } }, \
{ 510000000UL, { 844181, 0, 0 } }, \
{ 612000000UL, { 878147, 0, 0 } }, \
{ 714000000UL, { 912113, 0, 0 } }, \
{ 816000000UL, { 946079, 0, 0 } }, \
{ 918000000UL, { 980045, 0, 0 } }, \
{ 1020000000UL, { 1014011, 0, 0 } }, \
{ 1122000000UL, { 1047977, 0, 0 } }, \
{ 1224000000UL, { 1081943, 0, 0 } }, \
{ 1326000000UL, { 1090000, 0, 0 } }, \
{ 1479000000UL, { 1090000, 0, 0 } }, \
{ 1504500000UL, { 1120000, 0, 0 } }, \
{ 0UL, { 0, 0, 0 } }, \
{204000000UL, {742283, 0, 0} }, \
{306000000UL, {776249, 0, 0} }, \
{408000000UL, {810215, 0, 0} }, \
{510000000UL, {844181, 0, 0} }, \
{612000000UL, {878147, 0, 0} }, \
{714000000UL, {912113, 0, 0} }, \
{816000000UL, {946079, 0, 0} }, \
{918000000UL, {980045, 0, 0} }, \
{1020000000UL, {1014011, 0, 0} }, \
{1122000000UL, {1047977, 0, 0} }, \
{1224000000UL, {1081943, 0, 0} }, \
{1326000000UL, {1090000, 0, 0} }, \
{1479000000UL, {1090000, 0, 0} }, \
{1504500000UL, {1120000, 0, 0} }, \
{0, { 0, 0, 0} }, \
}
#define CPU_CVB_TABLE_ODN \
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
{ 204000000UL, { 721094, 0, 0 } }, \
{ 306000000UL, { 754040, 0, 0 } }, \
{ 408000000UL, { 786986, 0, 0 } }, \
{ 510000000UL, { 819932, 0, 0 } }, \
{ 612000000UL, { 852878, 0, 0 } }, \
{ 714000000UL, { 885824, 0, 0 } }, \
{ 816000000UL, { 918770, 0, 0 } }, \
{ 918000000UL, { 915716, 0, 0 } }, \
{ 1020000000UL, { 984662, 0, 0 } }, \
{ 1122000000UL, { 1017608, 0, 0 } }, \
{ 1224000000UL, { 1050554, 0, 0 } }, \
{ 1326000000UL, { 1083500, 0, 0 } }, \
{ 1428000000UL, { 1116446, 0, 0 } }, \
{ 1581000000UL, { 1130000, 0, 0 } }, \
{ 1683000000UL, { 1168000, 0, 0 } }, \
{ 1785000000UL, { 1227500, 0, 0 } }, \
{ 0UL, { 0, 0, 0 } }, \
{204000000UL, {721094, 0, 0} }, \
{306000000UL, {754040, 0, 0} }, \
{408000000UL, {786986, 0, 0} }, \
{510000000UL, {819932, 0, 0} }, \
{612000000UL, {852878, 0, 0} }, \
{714000000UL, {885824, 0, 0} }, \
{816000000UL, {918770, 0, 0} }, \
{918000000UL, {915716, 0, 0} }, \
{1020000000UL, {984662, 0, 0} }, \
{1122000000UL, {1017608, 0, 0} }, \
{1224000000UL, {1050554, 0, 0} }, \
{1326000000UL, {1083500, 0, 0} }, \
{1428000000UL, {1116446, 0, 0} }, \
{1581000000UL, {1130000, 0, 0} }, \
{1683000000UL, {1168000, 0, 0} }, \
{1785000000UL, {1227500, 0, 0} }, \
{0, { 0, 0, 0} }, \
}
static struct cvb_table tegra210_cpu_cvb_tables[] = {
struct cvb_table tegra210_cpu_cvb_tables[] = {
{
.speedo_id = 10,
.process_id = 0,
@@ -242,7 +248,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
.tune_high_min_millivolts = 864,
}
},
@@ -255,7 +261,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
.tune_high_min_millivolts = 864,
}
},
@@ -268,7 +274,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
}
},
{
@@ -280,7 +286,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
}
},
{
@@ -292,7 +298,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
}
},
{
@@ -304,7 +310,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
}
},
{
@@ -316,7 +322,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
.tune_high_min_millivolts = 864,
}
},
@@ -329,7 +335,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
.tune_high_min_millivolts = 864,
}
},
@@ -341,7 +347,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
CPU_CVB_TABLE,
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
}
},
{
@@ -352,7 +358,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
CPU_CVB_TABLE,
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune1 = 0x25501d0,
.tune1_low = 0x25501d0,
}
},
{
@@ -364,7 +370,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
.tune_high_min_millivolts = 864,
}
},
@@ -377,7 +383,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x25501d0,
.tune1_low = 0x25501d0,
.tune_high_min_millivolts = 864,
}
},
@@ -389,7 +395,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
CPU_CVB_TABLE_XA,
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune1 = 0x17711BD,
.tune1_low = 0x17711BD,
}
},
{
@@ -401,7 +407,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
.tune_high_min_millivolts = 864,
}
},
@@ -414,7 +420,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x25501d0,
.tune1_low = 0x25501d0,
.tune_high_min_millivolts = 864,
}
},
@@ -426,7 +432,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
CPU_CVB_TABLE,
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
}
},
{
@@ -437,7 +443,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
CPU_CVB_TABLE,
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune1 = 0x25501d0,
.tune1_low = 0x25501d0,
}
},
{
@@ -449,7 +455,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
.tune_high_min_millivolts = 864,
}
},
@@ -462,7 +468,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x25501d0,
.tune1_low = 0x25501d0,
.tune_high_min_millivolts = 864,
}
},
@@ -475,7 +481,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x20091d9,
.tune1_low = 0x20091d9,
.tune_high_min_millivolts = 864,
}
},
@@ -488,7 +494,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = {
.cpu_dfll_data = {
.tune0_low = 0xffead0ff,
.tune0_high = 0xffead0ff,
.tune1 = 0x25501d0,
.tune1_low = 0x25501d0,
.tune_high_min_millivolts = 864,
}
},
@@ -505,6 +511,7 @@ static const unsigned long tegra210b01_cpu_max_freq_table[] = {
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
/* f c0, c1, c2 */ \
{ 204000000UL, { 732856, -17335, 113 } }, \
{ 306000000UL, { 760024, -18195, 113 } }, \
{ 408000000UL, { 789258, -19055, 113 } }, \
@@ -525,13 +532,24 @@ static const unsigned long tegra210b01_cpu_max_freq_table[] = {
{ 1963500000UL, { 1490873, -32155, 113 } }, \
{ 2065500000UL, { 1553683, -33015, 113 } }, \
{ 2091000000UL, { 1580725, -33235, 113 } }, \
{ 0UL, { 0, 0, 0 } }, \
}
{ 0, { } }, \
}, \
.vmin_coefficients = { 600000, 0, 0 }, \
.cpu_dfll_data = { \
.tune0_low = 0x0000FFA0, \
.tune0_high = 0x0000FFFF, \
.tune1_low = 0x21107FF, \
.tune_high_min_millivolts = 850, \
.tune_high_margin_millivolts = 38, \
.dvco_calibration_max = ULONG_MAX, \
}, \
.cvb_version = "FCPU Table - p4v3-AggressiveSLT"
#define CPUB01_CVB_TABLE_SLT_B0 \
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
/* f c0, c1, c2 */ \
{ 204000000UL, { 732856, -17335, 113 } }, \
{ 306000000UL, { 760024, -18195, 113 } }, \
{ 408000000UL, { 789258, -19055, 113 } }, \
@@ -552,13 +570,24 @@ static const unsigned long tegra210b01_cpu_max_freq_table[] = {
{ 1963500000UL, { 1490873, -32155, 113 } }, \
{ 2065500000UL, { 1553683, -33015, 113 } }, \
{ 2091000000UL, { 1580725, -33235, 113 } }, \
{ 0UL, { 0, 0, 0 } }, \
}
{ 0, { } }, \
}, \
.vmin_coefficients = { 600000, 0, 0 }, \
.cpu_dfll_data = { \
.tune0_low = 0x0000FF90, \
.tune0_high = 0x0000FFFF, \
.tune1_low = 0x21107FF, \
.tune_high_min_millivolts = 850, \
.tune_high_margin_millivolts = 38, \
.dvco_calibration_max = ULONG_MAX, \
}, \
.cvb_version = "FCPU Table - p4v3-AggressiveSLT"
#define CPUB01_CVB_TABLE \
.speedo_scale = 100, \
.voltage_scale = 1000, \
.entries = { \
/* f c0, c1, c2 */ \
{ 204000000UL, { 721589, -12695, 27 } }, \
{ 306000000UL, { 747134, -14195, 27 } }, \
{ 408000000UL, { 776324, -15705, 27 } }, \
@@ -578,57 +607,100 @@ static const unsigned long tegra210b01_cpu_max_freq_table[] = {
{ 1887000000UL, { 1609246, -37515, 27 } }, \
{ 1963500000UL, { 1675751, -38635, 27 } }, \
{ 2014500000UL, { 1716501, -39395, 27 } }, \
{ 0UL, { 0, 0, 0 } }, \
}
{ 0, { } }, \
}, \
.vmin_coefficients = { 620000, 0, 0 }, \
.cpu_dfll_data = { \
.tune0_low = 0x0000FFCF, \
.tune1_low = 0x012207FF, \
.tune1_high = 0x03FFF7FF, \
.tune_high_min_millivolts = 850, \
.tune_high_margin_millivolts = 38, \
.dvco_calibration_max = ULONG_MAX, \
}, \
.cvb_version = "FCPU Table - p4v3"
static struct cvb_table tegra210b01_cpu_cvb_tables[] = {
struct cvb_table tegra210b01_cpu_cvb_tables[] = {
{
.speedo_id = 3,
.process_id = -1,
.max_millivolts = 1120,
CPUB01_CVB_TABLE,
.cpu_dfll_data = {
.tune0_low = 0x0000ffcf,
.tune1 = 0x012207ff,
.tune_high_min_millivolts = 850,
}
},
{
.speedo_id = 2,
.process_id = 1,
.max_millivolts = 1120,
CPUB01_CVB_TABLE_SLT_B1,
.cpu_dfll_data = {
.tune0_low = 0x0000ffa0,
.tune0_high = 0x0000ffff,
.tune1 = 0x021107ff,
.tune_high_min_millivolts = 850,
}
},
{
.speedo_id = 2,
.process_id = 0,
.max_millivolts = 1120,
CPUB01_CVB_TABLE_SLT_B0,
.cpu_dfll_data = {
.tune0_low = 0x0000ff90,
.tune0_high = 0x0000ffff,
.tune1 = 0x021107ff,
.tune_high_min_millivolts = 850,
}
},
{
.speedo_id = -1,
.process_id = -1,
.max_millivolts = 1120,
CPUB01_CVB_TABLE,
.cpu_dfll_data = {
.tune0_low = 0x0000ffcf,
.tune1 = 0x012207ff,
.tune_high_min_millivolts = 850,
}
},
};
static struct thermal_tv tegra210_thermal_floor_table[] = {
{TEGRA210_DFLL_THERMAL_FLOOR_0 / 1000, 950},
{DFLL_THERMAL_FLOOR_NOFLOOR / 1000, 0},
};
static const struct thermal_tv tegra210_thermal_cap_table[] = {
{DFLL_THERMAL_CAP_NOCAP / 1000, INT_MAX},
{TEGRA210_DFLL_THERMAL_CAP_0 / 1000, 1170},
{TEGRA210_DFLL_THERMAL_CAP_1 / 1000, 1132},
};
static const struct thermal_tv tegra210_thermal_cap_ucm2_table[] = {
{DFLL_THERMAL_CAP_NOCAP / 1000, INT_MAX},
{TEGRA210_DFLL_THERMAL_CAP_0 / 1000, 1162},
{TEGRA210_DFLL_THERMAL_CAP_1 / 1000, 1090},
};
static const struct thermal_table tegra210_cpu_thermal_table = {
.thermal_floor_table = tegra210_thermal_floor_table,
.thermal_floor_table_size = ARRAY_SIZE(tegra210_thermal_floor_table),
.coefficients = { {800000, 0, 0}, 0, 0, 0 },
.speedo_scale = 100,
.voltage_scale = 1000,
.temp_scale = 10,
.thermal_cap_table = tegra210_thermal_cap_table,
.thermal_cap_table_size = ARRAY_SIZE(tegra210_thermal_cap_table),
.thermal_cap_ucm2_table = tegra210_thermal_cap_ucm2_table,
.thermal_cap_ucm2_table_size = ARRAY_SIZE(tegra210_thermal_cap_ucm2_table),
};
static struct thermal_tv tegra210b01_thermal_floor_table[] = {
{TEGRA210B01_DFLL_THERMAL_FLOOR_0 / 1000, 800},
{TEGRA210B01_DFLL_THERMAL_FLOOR_1 / 1000, 0},
{DFLL_THERMAL_FLOOR_NOFLOOR / 1000, 0},
};
static const struct thermal_tv tegra210b01_thermal_cap_table[] = {
{DFLL_THERMAL_CAP_NOCAP / 1000, INT_MAX},
{TEGRA210B01_DFLL_THERMAL_CAP_0 / 1000, 1060},
{TEGRA210B01_DFLL_THERMAL_CAP_1 / 1000, 1010},
};
static const struct thermal_table tegra210b01_cpu_thermal_table = {
.thermal_floor_table = tegra210b01_thermal_floor_table,
.thermal_floor_table_size = ARRAY_SIZE(tegra210b01_thermal_floor_table),
.speedo_scale = 100,
.voltage_scale = 1000,
.temp_scale = 10,
.thermal_cap_table = tegra210b01_thermal_cap_table,
.thermal_cap_table_size = ARRAY_SIZE(tegra210b01_thermal_cap_table),
.thermal_cap_ucm2_table = tegra210b01_thermal_cap_table,
.thermal_cap_ucm2_table_size = ARRAY_SIZE(tegra210b01_thermal_cap_table)
};
static const struct dfll_fcpu_data tegra124_dfll_fcpu_data = {
.cpu_max_freq_table = tegra124_cpu_max_freq_table,
.cpu_max_freq_table_size = ARRAY_SIZE(tegra124_cpu_max_freq_table),
@@ -641,6 +713,7 @@ static const struct dfll_fcpu_data tegra210_dfll_fcpu_data = {
.cpu_max_freq_table_size = ARRAY_SIZE(tegra210_cpu_max_freq_table),
.cpu_cvb_tables = tegra210_cpu_cvb_tables,
.cpu_cvb_tables_size = ARRAY_SIZE(tegra210_cpu_cvb_tables),
.cpu_thermal_table = &tegra210_cpu_thermal_table
};
static const struct dfll_fcpu_data tegra210b01_dfll_fcpu_data = {
@@ -648,6 +721,7 @@ static const struct dfll_fcpu_data tegra210b01_dfll_fcpu_data = {
.cpu_max_freq_table_size = ARRAY_SIZE(tegra210b01_cpu_max_freq_table),
.cpu_cvb_tables = tegra210b01_cpu_cvb_tables,
.cpu_cvb_tables_size = ARRAY_SIZE(tegra210b01_cpu_cvb_tables),
.cpu_thermal_table = &tegra210b01_cpu_thermal_table
};
static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
@@ -669,44 +743,66 @@ static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
static void get_alignment_from_dt(struct device *dev,
struct rail_alignment *align)
{
align->step_uv = 0;
align->offset_uv = 0;
if (of_property_read_u32(dev->of_node,
"nvidia,pwm-voltage-step-microvolts",
&align->step_uv))
align->step_uv = 0;
if (of_property_read_u32(dev->of_node,
"nvidia,pwm-min-microvolts",
&align->offset_uv))
"nvidia,pwm-min-microvolts", &align->offset_uv))
align->offset_uv = 0;
}
static int get_alignment_from_regulator(struct device *dev,
struct rail_alignment *align)
{
struct regulator *reg = regulator_get(dev, "vdd-cpu");
int min_uV, max_uV, n_voltages, ret;
struct regulator *reg = devm_regulator_get(dev, "vdd-cpu");
if (IS_ERR(reg))
return PTR_ERR(reg);
align->offset_uv = regulator_list_voltage(reg, 0);
align->step_uv = regulator_get_linear_step(reg);
ret = regulator_get_constraint_voltages(reg, &min_uV, &max_uV);
if (!ret)
align->offset_uv = min_uV;
regulator_put(reg);
align->step_uv = regulator_get_linear_step(reg);
if (!align->step_uv && !ret) {
n_voltages = regulator_count_voltages(reg);
if (n_voltages > 1)
align->step_uv = (max_uV - min_uV) / (n_voltages - 1);
}
devm_regulator_put(reg);
return 0;
}
#define INIT_TUNE_PRAM(p) \
do { \
if (of_property_read_u32(pdev->dev.of_node, \
"nvidia,dfll-override-" #p, &soc->p)) \
soc->p = soc->cvb->cpu_dfll_data.p; \
} while (0)
static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
{
int process_id, speedo_id, speedo_value, err;
struct tegra_dfll_soc_data *soc;
const struct dfll_fcpu_data *fcpu_data;
struct rail_alignment align;
const struct thermal_table *thermal;
unsigned long max_freq;
u32 f;
bool ucm2;
fcpu_data = of_device_get_match_data(&pdev->dev);
if (!fcpu_data)
return -ENODEV;
ucm2 = tegra_sku_info.ucm == TEGRA_UCM2;
process_id = tegra_sku_info.cpu_process_id;
speedo_id = tegra_sku_info.cpu_speedo_id;
speedo_value = tegra_sku_info.cpu_speedo_value;
@@ -716,6 +812,10 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
speedo_id);
return -ENODEV;
}
max_freq = fcpu_data->cpu_max_freq_table[speedo_id];
if (!of_property_read_u32(pdev->dev.of_node, "nvidia,dfll-max-freq-khz",
&f))
max_freq = min(max_freq, f * 1000UL);
soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL);
if (!soc)
@@ -727,20 +827,33 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
return -ENODEV;
}
if (of_property_read_bool(pdev->dev.of_node, "nvidia,pwm-to-pmic")) {
get_alignment_from_dt(&pdev->dev, &align);
if (of_property_read_bool(pdev->dev.of_node, "nvidia,pwm-to-pmic")
&& (!align.step_uv || !align.offset_uv)) {
dev_info(&pdev->dev, "Missing required align data in DT");
return -EINVAL;
} else {
if (!align.step_uv) {
dev_info(&pdev->dev, "no align data in DT, try from vdd-cpu\n");
err = get_alignment_from_regulator(&pdev->dev, &align);
if (err)
return err;
if (err == -EPROBE_DEFER) {
dev_info(&pdev->dev, "defer probe to get vdd-cpu\n");
return -EPROBE_DEFER;
}
}
}
soc->max_freq = fcpu_data->cpu_max_freq_table[speedo_id];
if (!align.step_uv) {
dev_err(&pdev->dev, "missing step uv\n");
return -EINVAL;
}
soc->max_freq = max_freq;
soc->cvb = tegra_cvb_add_opp_table(soc->dev, fcpu_data->cpu_cvb_tables,
fcpu_data->cpu_cvb_tables_size,
&align, process_id, speedo_id,
speedo_value, soc->max_freq);
speedo_value, soc->max_freq,
&soc->min_millivolts);
soc->alignment = align;
if (IS_ERR(soc->cvb)) {
@@ -749,6 +862,33 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
return PTR_ERR(soc->cvb);
}
INIT_TUNE_PRAM(tune0_low);
INIT_TUNE_PRAM(tune0_high);
INIT_TUNE_PRAM(tune1_low);
INIT_TUNE_PRAM(tune1_high);
INIT_TUNE_PRAM(tune_high_min_millivolts);
INIT_TUNE_PRAM(tune_high_margin_millivolts);
thermal = fcpu_data->cpu_thermal_table;
err = tegra_cvb_build_thermal_table(thermal, speedo_value,
soc->min_millivolts);
if (err < 0) {
pr_warn("couldn't build thermal floor table\n");
} else {
soc->thermal_floor_table = thermal->thermal_floor_table;
soc->thermal_floor_table_size = thermal->thermal_floor_table_size;
}
if (thermal && thermal->thermal_cap_table && !ucm2) {
soc->thermal_cap_table = thermal->thermal_cap_table;
soc->thermal_cap_table_size = thermal->thermal_cap_table_size;
} else if (thermal && thermal->thermal_cap_ucm2_table && ucm2) {
soc->thermal_cap_table = thermal->thermal_cap_ucm2_table;
soc->thermal_cap_table_size = thermal->thermal_cap_ucm2_table_size;
} else {
pr_warn("couldn't get thermal cap table\n");
}
err = tegra_dfll_register(pdev, soc);
if (err < 0) {
tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
@@ -762,13 +902,10 @@ static void tegra124_dfll_fcpu_remove(struct platform_device *pdev)
{
struct tegra_dfll_soc_data *soc;
/*
* Note that exiting early here is dangerous as after this function
* returns *soc is freed.
*/
soc = tegra_dfll_unregister(pdev);
if (IS_ERR(soc))
return;
dev_err(&pdev->dev, "failed to unregister DFLL: %ld\n",
PTR_ERR(soc));
tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
}
@@ -776,7 +913,7 @@ static void tegra124_dfll_fcpu_remove(struct platform_device *pdev)
static const struct dev_pm_ops tegra124_dfll_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend,
tegra_dfll_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(tegra_dfll_suspend, tegra_dfll_resume)
SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, tegra_dfll_resume_tuning)
};
static struct platform_driver tegra124_dfll_fcpu_driver = {

View File

@@ -11,7 +11,7 @@
#include "cvb.h"
/* cvb_mv = ((c2 * speedo / s_scale + c1) * speedo / s_scale + c0) */
static inline int get_cvb_voltage(int speedo, int s_scale,
int tegra_get_cvb_voltage(int speedo, int s_scale,
const struct cvb_coefficients *cvb)
{
int mv;
@@ -22,7 +22,20 @@ static inline int get_cvb_voltage(int speedo, int s_scale,
return mv;
}
static int round_cvb_voltage(int mv, int v_scale,
/* cvb_t_mv =
((c3 * speedo / s_scale + c4 + c5 * T / t_scale) * T / t_scale) / v_scale */
int tegra_get_cvb_t_voltage(int speedo, int s_scale, int t, int t_scale,
struct cvb_coefficients *cvb)
{
/* apply speedo & temperature scales: output mv = cvb_t_mv * v_scale */
int mv;
mv = DIV_ROUND_CLOSEST(cvb->c3 * speedo, s_scale) + cvb->c4 +
DIV_ROUND_CLOSEST(cvb->c5 * t, t_scale);
mv = DIV_ROUND_CLOSEST(mv * t, t_scale);
return mv;
}
int tegra_round_cvb_voltage(int mv, int v_scale,
const struct rail_alignment *align)
{
/* combined: apply voltage scale and round to cvb alignment step */
@@ -40,7 +53,7 @@ enum {
UP
};
static int round_voltage(int mv, const struct rail_alignment *align, int up)
int tegra_round_voltage(int mv, const struct rail_alignment *align, int up)
{
if (align->step_uv) {
int uv;
@@ -52,14 +65,46 @@ static int round_voltage(int mv, const struct rail_alignment *align, int up)
return mv;
}
/**
* cvb_t_mv =
* ((c2 * speedo / s_scale + c1) * speedo / s_scale + c0) +
* ((c3 * speedo / s_scale + c4 + c5 * T / t_scale) * T / t_scale)
*/
static inline int get_cvb_thermal_floor(int speedo, int temp,
int s_scale, int t_scale,
const struct thermal_coefficients *coef)
{
int cvb_mv, mv;
cvb_mv = tegra_get_cvb_voltage(speedo, s_scale, &coef->cvb_coef);
mv = DIV_ROUND_CLOSEST(coef->c3 * speedo, s_scale) + coef->c4 +
DIV_ROUND_CLOSEST(coef->c5 * temp, t_scale);
mv = DIV_ROUND_CLOSEST(mv * temp, t_scale) + cvb_mv;
return mv;
}
static int build_opp_table(struct device *dev, const struct cvb_table *table,
struct rail_alignment *align,
int speedo_value, unsigned long max_freq)
int speedo_value, unsigned long max_freq, int *vmin)
{
int i, ret, dfll_mv, min_mv, max_mv;
min_mv = round_voltage(table->min_millivolts, align, UP);
max_mv = round_voltage(table->max_millivolts, align, DOWN);
if (!align->step_uv)
align->step_uv = table->alignment.step_uv;
if (!align->step_uv)
return -EINVAL;
if (!align->offset_uv)
align->offset_uv = table->alignment.offset_uv;
min_mv = tegra_round_voltage(table->min_millivolts, align, UP);
max_mv = tegra_round_voltage(table->max_millivolts, align, DOWN);
dfll_mv = tegra_get_cvb_voltage(
speedo_value, table->speedo_scale, &table->vmin_coefficients);
dfll_mv = tegra_round_cvb_voltage(dfll_mv, table->voltage_scale, align);
min_mv = max(min_mv, dfll_mv);
for (i = 0; i < MAX_DVFS_FREQS; i++) {
const struct cvb_table_freq_entry *entry = &table->entries[i];
@@ -67,10 +112,9 @@ static int build_opp_table(struct device *dev, const struct cvb_table *table,
if (!entry->freq || (entry->freq > max_freq))
break;
dfll_mv = get_cvb_voltage(speedo_value, table->speedo_scale,
&entry->coefficients);
dfll_mv = round_cvb_voltage(dfll_mv, table->voltage_scale,
align);
dfll_mv = tegra_get_cvb_voltage(
speedo_value, table->speedo_scale, &entry->coefficients);
dfll_mv = tegra_round_cvb_voltage(dfll_mv, table->voltage_scale, align);
dfll_mv = clamp(dfll_mv, min_mv, max_mv);
ret = dev_pm_opp_add(dev, entry->freq, dfll_mv * 1000);
@@ -78,32 +122,35 @@ static int build_opp_table(struct device *dev, const struct cvb_table *table,
return ret;
}
if (vmin)
*vmin = min_mv;
return 0;
}
/**
* tegra_cvb_add_opp_table - build OPP table from Tegra CVB tables
* @dev: the struct device * for which the OPP table is built
* @tables: array of CVB tables
* @count: size of the previously mentioned array
* @align: parameters of the regulator step and offset
* @cvb_tables: array of CVB tables
* @sz: size of the previously mentioned array
* @process_id: process id of the HW module
* @speedo_id: speedo id of the HW module
* @speedo_value: speedo value of the HW module
* @max_freq: highest safe clock rate
* @max_rate: highest safe clock rate
* @opp_dev: the struct device * for which the OPP table is built
* @vmin: final minimum voltage returned to the caller
*
* On Tegra, a CVB table encodes the relationship between operating voltage
* and safe maximal frequency for a given module (e.g. GPU or CPU). This
* function calculates the optimal voltage-frequency operating points
* for the given arguments and exports them via the OPP library for the
* given @dev. Returns a pointer to the struct cvb_table that matched
* given @opp_dev. Returns a pointer to the struct cvb_table that matched
* or an ERR_PTR on failure.
*/
const struct cvb_table *
tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *tables,
size_t count, struct rail_alignment *align,
int process_id, int speedo_id, int speedo_value,
unsigned long max_freq)
unsigned long max_freq, int *vmin)
{
size_t i;
int ret;
@@ -118,7 +165,7 @@ tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *tables,
continue;
ret = build_opp_table(dev, table, align, speedo_value,
max_freq);
max_freq, vmin);
return ret ? ERR_PTR(ret) : table;
}
@@ -140,3 +187,41 @@ void tegra_cvb_remove_opp_table(struct device *dev,
dev_pm_opp_remove(dev, entry->freq);
}
}
/**
* tegra_cvb_build_thermal_table - build thermal table from Tegra CVB tables
* @table: the hardware characterization thermal table
* @speedo_value: speedo value of the HW module
* @soc_min_mv: minimum voltage applied across all temperature ranges
*
* The minimum voltage for the IP blocks inside Tegra SoCs might depend on
* the current temperature. This function calculates the voltage-thermal
* relations according to the given coefficients. Note that if the
* coefficients are not defined, the fixed thermal floors in the @table will
* be used. Returns 0 on success or a negative error code on failure.
*/
int tegra_cvb_build_thermal_table(const struct thermal_table *table,
int speedo_value, unsigned int soc_min_mv)
{
int i;
if (!table)
return -EINVAL;
/* The vmin for the lowest trip point is fixed */
for (i = 1; i < table->thermal_floor_table_size; i++) {
unsigned int mv;
mv = get_cvb_thermal_floor(speedo_value,
table->thermal_floor_table[i-1].temp,
table->speedo_scale,
table->temp_scale,
&table->coefficients);
mv = DIV_ROUND_UP(mv, table->voltage_scale);
mv = max(mv, soc_min_mv);
table->thermal_floor_table[i].millivolts = max(mv,
table->thermal_floor_table[i].millivolts);
}
return 0;
}

View File

@@ -21,6 +21,9 @@ struct cvb_coefficients {
int c0;
int c1;
int c2;
int c3;
int c4;
int c5;
};
struct cvb_table_freq_entry {
@@ -31,8 +34,24 @@ struct cvb_table_freq_entry {
struct cvb_cpu_dfll_data {
u32 tune0_low;
u32 tune0_high;
u32 tune1;
u32 tune1_low;
u32 tune1_high;
unsigned int tune_high_min_millivolts;
unsigned int tune_high_margin_millivolts;
unsigned long dvco_calibration_max;
};
struct thermal_coefficients {
struct cvb_coefficients cvb_coef;
int c3;
int c4;
int c5;
};
/* Thermal trips and voltages */
struct thermal_tv {
int temp;
unsigned int millivolts;
};
struct cvb_table {
@@ -41,20 +60,57 @@ struct cvb_table {
int min_millivolts;
int max_millivolts;
struct rail_alignment alignment;
int speedo_scale;
int voltage_scale;
struct cvb_table_freq_entry entries[MAX_DVFS_FREQS];
struct cvb_cpu_dfll_data cpu_dfll_data;
struct cvb_coefficients vmin_coefficients;
const char *cvb_version;
};
const struct cvb_table *
tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *cvb_tables,
size_t count, struct rail_alignment *align,
int process_id, int speedo_id, int speedo_value,
unsigned long max_freq);
unsigned long max_freq, int *vmin);
void tegra_cvb_remove_opp_table(struct device *dev,
const struct cvb_table *table,
unsigned long max_freq);
struct thermal_table {
struct thermal_tv *thermal_floor_table;
unsigned int thermal_floor_table_size;
struct thermal_coefficients coefficients;
unsigned int speedo_scale;
unsigned int voltage_scale;
unsigned int temp_scale;
const struct thermal_tv *thermal_cap_table;
unsigned int thermal_cap_table_size;
const struct thermal_tv *thermal_cap_ucm2_table;
unsigned int thermal_cap_ucm2_table_size;
};
const struct cvb_table *tegra_cvb_build_opp_table(
const struct cvb_table *cvb_tables,
size_t sz,
const struct rail_alignment *align,
int process_id,
int speedo_id,
int speedo_value,
unsigned long max_rate,
struct device *opp_dev);
int tegra_get_cvb_voltage(int speedo, int s_scale,
const struct cvb_coefficients *cvb);
int tegra_round_cvb_voltage(int mv, int v_scale,
const struct rail_alignment *align);
int tegra_round_voltage(int mv, const struct rail_alignment *align, int up);
int tegra_get_cvb_t_voltage(int speedo, int s_scale, int t, int t_scale,
struct cvb_coefficients *cvb);
int tegra_cvb_build_thermal_table(const struct thermal_table *table,
int speedo_value, unsigned int soc_min_mv);
#endif

View File

@@ -134,5 +134,6 @@ int gf100_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
int gk104_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gk20a_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gm20b_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gm20b_b01_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
int gp10b_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_clk **);
#endif

View File

@@ -42,4 +42,5 @@ int gf117_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
int gk104_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
int gk20a_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
int gm20b_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
int gm20b_b01_volt_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_volt **);
#endif

View File

@@ -2072,6 +2072,31 @@ nv12b_chipset = {
.sw = { 0x00000001, gf100_sw_new },
};
static const struct nvkm_device_chip
nv12e_chipset = {
.name = "GM20B",
.acr = { 0x00000001, gm20b_acr_new },
.bar = { 0x00000001, gm20b_bar_new },
.bus = { 0x00000001, gf100_bus_new },
.clk = { 0x00000001, gm20b_b01_clk_new },
.fb = { 0x00000001, gm20b_fb_new },
.fuse = { 0x00000001, gm107_fuse_new },
.imem = { 0x00000001, gk20a_instmem_new },
.ltc = { 0x00000001, gm200_ltc_new },
.mc = { 0x00000001, gk20a_mc_new },
.mmu = { 0x00000001, gm20b_mmu_new },
.pmu = { 0x00000001, gm20b_pmu_new },
.privring = { 0x00000001, gk20a_privring_new },
.timer = { 0x00000001, gk20a_timer_new },
.top = { 0x00000001, gk104_top_new },
.volt = { 0x00000001, gm20b_b01_volt_new },
.ce = { 0x00000004, gm200_ce_new },
.dma = { 0x00000001, gf119_dma_new },
.fifo = { 0x00000001, gm200_fifo_new },
.gr = { 0x00000001, gm20b_gr_new },
.sw = { 0x00000001, gf100_sw_new },
};
static const struct nvkm_device_chip
nv130_chipset = {
.name = "GP100",
@@ -3225,6 +3250,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x124: device->chip = &nv124_chipset; break;
case 0x126: device->chip = &nv126_chipset; break;
case 0x12b: device->chip = &nv12b_chipset; break;
case 0x12e: device->chip = &nv12e_chipset; break;
case 0x130: device->chip = &nv130_chipset; break;
case 0x132: device->chip = &nv132_chipset; break;
case 0x134: device->chip = &nv134_chipset; break;

View File

@@ -717,6 +717,112 @@ gm20b_pstates[] = {
},
};
static struct nvkm_pstate
gm20b_b01_pstates[] = {
{
.base = {
.domain[nv_clk_src_gpc] = 76800,
.voltage = 0,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 153600,
.voltage = 1,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 230400,
.voltage = 2,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 307200,
.voltage = 3,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 384000,
.voltage = 4,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 460800,
.voltage = 5,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 537600,
.voltage = 6,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 614400,
.voltage = 7,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 691200,
.voltage = 8,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 768000,
.voltage = 9,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 844800,
.voltage = 10,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 921600,
.voltage = 11,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 998400,
.voltage = 12,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 1075200,
.voltage = 13,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 1152000,
.voltage = 14,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 1228800,
.voltage = 15,
},
},
{
.base = {
.domain[nv_clk_src_gpc] = 1267200,
.voltage = 16,
},
},
};
static void
gm20b_clk_fini(struct nvkm_clk *base)
{
@@ -912,6 +1018,41 @@ gm20b_clk = {
},
};
static const struct nvkm_clk_func
gm20b_b01_clk = {
.init = gm20b_clk_init,
.fini = gk20a_clk_fini,
.read = gk20a_clk_read,
.calc = gk20a_clk_calc,
.prog = gk20a_clk_prog,
.tidy = gk20a_clk_tidy,
.pstates = gm20b_b01_pstates,
.nr_pstates = ARRAY_SIZE(gm20b_b01_pstates),
.domains = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV },
{ nv_clk_src_max },
},
};
static const struct nvkm_clk_func
gm20b_b01_hiopt_clk_speedo = {
.init = gm20b_clk_init,
.fini = gk20a_clk_fini,
.read = gk20a_clk_read,
.calc = gk20a_clk_calc,
.prog = gk20a_clk_prog,
.tidy = gk20a_clk_tidy,
.pstates = gm20b_pstates,
/* HIOPT speedo only supports 16 voltages */
.nr_pstates = ARRAY_SIZE(gm20b_pstates) - 1,
.domains = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV },
{ nv_clk_src_max },
},
};
static int
gm20b_clk_new_speedo0(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_clk **pclk)
@@ -930,6 +1071,24 @@ gm20b_clk_new_speedo0(struct nvkm_device *device, enum nvkm_subdev_type type, in
return ret;
}
static int
gm20b_b01_clk_new_hiopt(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_clk **pclk)
{
struct gk20a_clk *clk;
int ret;
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk)
return -ENOMEM;
*pclk = &clk->base;
ret = gk20a_clk_ctor(device, type, inst, &gm20b_b01_hiopt_clk_speedo, &gm20b_pllg_params, clk);
clk->pl_to_div = pl_to_div;
clk->div_to_pl = div_to_pl;
return ret;
}
/* FUSE register */
#define FUSE_RESERVED_CALIB0 0x204
#define FUSE_RESERVED_CALIB0_INTERCEPT_FRAC_SHIFT 0
@@ -1074,3 +1233,63 @@ gm20b_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
return 0;
}
int
gm20b_b01_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_clk **pclk)
{
struct nvkm_device_tegra *tdev = device->func->tegra(device);
struct gm20b_clk *clk;
struct nvkm_subdev *subdev;
struct gk20a_clk_pllg_params *clk_params;
int ret;
/* Speedo 0 GPUs cannot use noise-aware PLL */
if (tdev->gpu_speedo_id == 0)
return gm20b_b01_clk_new_hiopt(device, type, inst, pclk);
/* Speedo >= 1, use NAPLL */
clk = kzalloc(sizeof(*clk) + sizeof(*clk_params), GFP_KERNEL);
if (!clk)
return -ENOMEM;
*pclk = &clk->base.base;
subdev = &clk->base.base.subdev;
/* duplicate the clock parameters since we will patch them below */
clk_params = (void *) (clk + 1);
*clk_params = gm20b_pllg_params;
ret = gk20a_clk_ctor(device, type, inst, &gm20b_b01_clk, clk_params, &clk->base);
if (ret)
return ret;
/*
* NAPLL can only work with max_u, clamp the m range so
* gk20a_pllg_calc_mnp always uses it
*/
clk_params->max_m = clk_params->min_m = DIV_ROUND_UP(clk_params->max_u,
(clk->base.parent_rate / KHZ));
if (clk_params->max_m == 0) {
nvkm_warn(subdev, "cannot use NAPLL, using legacy clock...\n");
kfree(clk);
return gm20b_b01_clk_new_hiopt(device, type, inst, pclk);
}
clk->base.pl_to_div = pl_to_div;
clk->base.div_to_pl = div_to_pl;
clk->dvfs_params = &gm20b_dvfs_params;
ret = gm20b_clk_init_fused_params(clk);
/*
* we will calibrate during init - should never happen on
* prod parts
*/
if (ret)
nvkm_warn(subdev, "no fused calibration parameters\n");
ret = gm20b_clk_init_safe_fmax(clk);
if (ret)
return ret;
return 0;
}

View File

@@ -91,3 +91,99 @@ gm20b_volt_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
return gk20a_volt_ctor(device, type, inst, gm20b_cvb_coef,
ARRAY_SIZE(gm20b_cvb_coef), vmin, volt);
}
static const struct cvb_coef gm20b_b01_na_cvb_slt_coef[] = {
/* KHz, c0, c1, c2, c3, c4, c5 */
/* 76800 */ { 590000, 0, 0, 0, 0, 0 },
/* 153600 */ { 590000, 0, 0, 0, 0, 0 },
/* 230400 */ { 590000, 0, 0, 0, 0, 0 },
/* 307200 */ { 590000, 0, 0, 0, 0, 0 },
/* 384000 */ { 590000, 0, 0, 0, 0, 0 },
/* 460800 */ { 795089, -11096, -163, 298, -10421, 162},
/* 537600 */ { 795089, -11096, -163, 298, -10421, 162 },
/* 614400 */ { 820606, -6285, -452, 238, -6182, 81 },
/* 691200 */ { 846289, -4565, -552, 119, -3958, -2 },
/* 768000 */ { 888720, -5110, -584, 0, -2849, 39 },
/* 844800 */ { 936634, -6089, -602, -60, -99, -93 },
/* 921600 */ { 982562, -7373, -614, -179, 1797, -13 },
/* 998400 */ { 1090179, -14125, -497, -179, 3518, 9 },
/* 1075200 */ { 1155798, -13465, -648, 0, 1077, 40 },
/* 1152000 */ { 1198568, -10904, -830, 0, 1469, 110 },
/* 1228800 */ { 1269988, -12707, -859, 0, 3722, 313 },
/* 1267200 */ { 1308155, -13694, -867, 0, 3681, 559 },
};
static const struct cvb_coef gm20b_b01_na_cvb_coef[] = {
/* KHz, c0, c1, c2, c3, c4, c5 */
/* 76800 */ { 610000, 0, 0, 0, 0, 0 },
/* 153600 */ { 610000, 0, 0, 0, 0, 0 },
/* 230400 */ { 610000, 0, 0, 0, 0, 0 },
/* 307200 */ { 610000, 0, 0, 0, 0, 0 },
/* 384000 */ { 610000, 0, 0, 0, 0, 0 },
/* 460800 */ { 610000, 0, 0, 0, 0, 0 },
/* 537600 */ { 801688, -10900, -163, 298, -10599, 162 },
/* 614400 */ { 824214, -5743, -452, 238, -6325, 81 },
/* 691200 */ { 848830, -3903, -552, 119, -4030, -2 },
/* 768000 */ { 891575, -4409, -584, 0, -2849, 39 },
/* 844800 */ { 940071, -5367, -602, -60, -63, -93 },
/* 921600 */ { 986765, -6637, -614, -179, 1905, -13 },
/* 998400 */ { 1098475, -13529, -497, -179, 3626, 9 },
/* 1075200 */ { 1163644, -12688, -648, 0, 1077, 40 },
/* 1152000 */ { 1204812, -9908, -830, 0, 1469, 110 },
/* 1228800 */ { 1277303, -11675, -859, 0, 3722, 313 },
/* 1267200 */ { 1335531, -12567, -867, 0, 3681, 559 },
};
static const struct cvb_coef gm20b_b01_na_cvb_hiopt_coef[] = {
/* KHz, c0, c1, c2, c3, c4, c5 */
/* 76800 */ { 590000, 0, 0, 0, 0, 0 },
/* 153600 */ { 590000, 0, 0, 0, 0, 0 },
/* 230400 */ { 590000, 0, 0, 0, 0, 0 },
/* 307200 */ { 590000, 0, 0, 0, 0, 0 },
/* 384000 */ { 590000, 0, 0, 0, 0, 0 },
/* 460800 */ { 590000, 0, 0, 0, 0, 0 },
/* 537600 */ { 590000, 0, 0, 0, 0, 0 },
/* 614400 */ { 590000, 0, 0, 0, 0, 0 },
/* 691200 */ { 838712, -7304, -552, 1785, -56250, -450 },
/* 768000 */ { 880210, -7955, -584, 0, -42735, 8775 },
/* 844800 */ { 926398, -8892, -602, -900, -5760, -20925 },
/* 921600 */ { 970060, -10108, -614, -2685, 22620, -2925 },
/* 998400 */ { 1065665, -16075, -497, -2685, 48195, 2025 },
/* 1075200 */ { 1132576, -16093, -648, 0, 16155, 9000 },
/* 1152000 */ { 1180029, -14534, -830, 0, 22035, 24750 },
/* 1228800 */ { 1248293, -16383, -859, 0, 55830, 70425 },
};
int
gm20b_b01_volt_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_volt **pvolt)
{
struct nvkm_device_tegra *tdev = device->func->tegra(device);
struct gk20a_volt *volt;
u32 vmin;
if (tdev->gpu_speedo_id >= ARRAY_SIZE(speedo_to_vmin)) {
nvdev_error(device, "unsupported speedo %d\n",
tdev->gpu_speedo_id);
return -EINVAL;
}
volt = kzalloc(sizeof(*volt), GFP_KERNEL);
if (!volt)
return -ENOMEM;
*pvolt = &volt->base;
vmin = speedo_to_vmin[tdev->gpu_speedo_id];
switch (tdev->gpu_speedo_id) {
case 3: /* HIOPT table */
return gk20a_volt_ctor(device, type, inst, gm20b_b01_na_cvb_hiopt_coef,
ARRAY_SIZE(gm20b_b01_na_cvb_hiopt_coef), vmin, volt);
case 2: /* SLT table */
return gk20a_volt_ctor(device, type, inst, gm20b_b01_na_cvb_slt_coef,
ARRAY_SIZE(gm20b_b01_na_cvb_slt_coef), vmin, volt);
default:
return gk20a_volt_ctor(device, type, inst, gm20b_b01_na_cvb_coef,
ARRAY_SIZE(gm20b_b01_na_cvb_coef), vmin, volt);
}
}

View File

@@ -282,6 +282,15 @@ config DRM_PANEL_JDI_LPM102A188A
The panel has a 2560×1800 resolution. It provides a MIPI DSI interface
to the host.
config DRM_PANEL_NX_DSI
tristate "Nintendo Switch 720x1280 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 DSI panels
used in the Nintendo Switch.
config DRM_PANEL_JDI_LT070ME05000
tristate "JDI LT070ME05000 WUXGA DSI panel"
depends on OF

View File

@@ -50,6 +50,7 @@ obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36523) += panel-novatek-nt36523.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672E) += panel-novatek-nt36672e.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
obj-$(CONFIG_DRM_PANEL_NX_DSI) += panel-nx-dsi.o
obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o
obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
obj-$(CONFIG_DRM_PANEL_ORISETECH_OTA5601A) += panel-orisetech-ota5601a.o

View File

@@ -0,0 +1,795 @@
/*
* Copyright (C) 2018 SwtcR <swtcr0@gmail.com>
* Copyright (C) 2023-2024 Azkali <a.ffcc7@gmail.com>
*
* Based on Sharp ls043t1le01 panel driver by Werner Johansson <werner.johansson@sonymobile.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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_crtc.h>
#include <drm/drm_panel.h>
#include <drm/drm_modes.h>
/*! MIPI DCS Panel Private CMDs. */
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE ((u8)0xA0)
#define MIPI_DCS_PRIV_SM_SET_REG_OFFSET ((u8)0xB0)
#define MIPI_DCS_PRIV_SM_SET_ELVSS ((u8)0xB1) /* OLED backlight tuning. Byte7: PWM transition time in frames. */
#define MIPI_DCS_PRIV_SET_POWER_CONTROL ((u8)0xB1)
#define MIPI_DCS_PRIV_SET_EXTC ((u8)0xB9) /* Enable extended commands. */
#define MIPI_DCS_PRIV_UNK_BD ((u8)0xBD)
#define MIPI_DCS_PRIV_UNK_D5 ((u8)0xD5)
#define MIPI_DCS_PRIV_UNK_D6 ((u8)0xD6)
#define MIPI_DCS_PRIV_UNK_D8 ((u8)0xD8)
#define MIPI_DCS_PRIV_UNK_D9 ((u8)0xD9)
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK ((u8)0xE2)
/* BL Control */
#define DCS_CONTROL_DISPLAY_SM_FLASHLIGHT ((u8)BIT(2))
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL ((u8)BIT(2))
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL ((u8)BIT(3))
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL ((u8)BIT(5))
/* OLED Panels color mode */
#define DCS_SM_COLOR_MODE_SATURATED ((u8)0x00) /* Disabled. Similar to vivid but over-saturated. Wide gamut? */
#define DCS_SM_COLOR_MODE_WASHED ((u8)0x45)
#define DCS_SM_COLOR_MODE_BASIC ((u8)0x03)
#define DCS_SM_COLOR_MODE_POR_RESET ((u8)0x20) /* Reset value on power on. */
#define DCS_SM_COLOR_MODE_NATURAL ((u8)0x23) /* Not actually natural.. */
#define DCS_SM_COLOR_MODE_VIVID ((u8)0x65)
#define DCS_SM_COLOR_MODE_NIGHT0 ((u8)0x43) /* Based on washed out. */
#define DCS_SM_COLOR_MODE_NIGHT1 ((u8)0x15) /* Based on basic. */
#define DCS_SM_COLOR_MODE_NIGHT2 ((u8)0x35) /* Based on natural. */
#define DCS_SM_COLOR_MODE_NIGHT3 ((u8)0x75) /* Based on vivid. */
#define DCS_SM_COLOR_MODE_ENABLE ((u8)BIT(0))
enum
{
PANEL_JDI_XXX062M = 0x10,
PANEL_JDI_LAM062M109A = 0x0910,
PANEL_JDI_LPM062M326A = 0x2610,
PANEL_INL_P062CCA_AZ1 = 0x0F20,
PANEL_AUO_A062TAN01 = 0x0F30,
PANEL_INL_2J055IA_27A = 0x1020,
PANEL_AUO_A055TAN01 = 0x1030,
PANEL_SHP_LQ055T1SW10 = 0x1040,
PANEL_SAM_AMS699VC01 = 0x2050,
PANEL_RR_SUPER5_OLED_V1 = 0x10E0,
PANEL_RR_SUPER5_OLED_HD_V1 = 0x10E1,
PANEL_RR_SUPER7_IPS_V1 = 0x0FE0,
PANEL_RR_SUPER7_IPS_HD_V1 = 0x0FE1,
PANEL_RR_SUPER7_OLED_7_V1 = 0x20E0,
PANEL_RR_SUPER7_OLED_HD_7_V1 = 0x20E1,
// Found on 6/2" clones. Unknown markings. Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F].
PANEL_OEM_CLONE_6_2 = 0x0F83,
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
PANEL_OEM_CLONE_5_5 = 0x00B3,
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
PANEL_OEM_CLONE = 0x0000
};
struct init_cmd {
u8 cmd;
int length;
u8 data[64];
};
struct nx_panel {
struct drm_panel base;
struct mipi_dsi_device *dsi;
struct backlight_device *backlight;
struct regulator *supply1;
struct regulator *supply2;
struct gpio_desc *reset_gpio;
bool prepared;
bool enabled;
const struct drm_display_mode *mode;
struct init_cmd *init_cmds;
struct init_cmd *suspend_cmds;
u16 display_id;
};
struct init_cmd init_cmds_default[] = {
{ MIPI_DCS_EXIT_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
120,
},
{ MIPI_DCS_SET_DISPLAY_ON, 2, { 0x00, 0x0 } },
{
0xFF,
20,
},
};
struct init_cmd init_cmds_PANEL_JDI_XXX062M[] = {
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0xFF, 0x83, 0x94 } },
{ MIPI_DCS_PRIV_UNK_BD, 2, { 0x00, 0x0 } },
{ MIPI_DCS_PRIV_UNK_D8, 24, { 0xAA, 0xAA, 0xAA, 0xEB, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xEB, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xEB, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xEB, 0xAA, 0xAA } },
{ MIPI_DCS_PRIV_UNK_BD, 2, { 0x01, 0x0 } },
{ MIPI_DCS_PRIV_UNK_D8,
38,
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } },
{ MIPI_DCS_PRIV_UNK_BD, 2, { 0x02, 0x0 } },
{ MIPI_DCS_PRIV_UNK_D8,
14,
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF } },
{ MIPI_DCS_PRIV_UNK_BD, 2, { 0x00, 0x00 } },
{ MIPI_DCS_PRIV_UNK_D9, 2, { 0x06, 0x0 } },
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0x00, 0x00, 0x00 } },
{ MIPI_DCS_EXIT_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
180,
},
{ MIPI_DCS_SET_DISPLAY_ON, 2, { 0x00, 0x0 } },
{
0xFF,
20,
},
{ MIPI_DCS_NOP, -1, { 0x00 } },
};
struct init_cmd suspend_cmds_PANEL_JDI_XXX062M[] = {
{ MIPI_DCS_SET_DISPLAY_OFF, 2, { 0x00, 0x0 } },
{
0xFF,
50,
},
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0xFF, 0x83, 0x94 } },
{ MIPI_DCS_PRIV_UNK_D5,
32,
{ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 } },
{ MIPI_DCS_PRIV_SET_POWER_CONTROL,
10,
{ 0x41, 0x0F, 0x4F, 0x33, 0xA4, 0x79, 0xF1, 0x81, 0x2D, 0x00 } },
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0x00, 0x00, 0x00 } },
{ MIPI_DCS_ENTER_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
50,
},
{ MIPI_DCS_NOP, -1, { 0x00 } },
};
struct init_cmd init_cmds_PANEL_SAM_AMS699VC01[] = {
{ MIPI_DCS_EXIT_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
180,
},
// Set color mode to basic (natural). Stock is Saturated (0x00). (Reset value is 0x20).
{ MIPI_DCS_PRIV_SM_SET_COLOR_MODE, 2, { 0x23, 0x0 } },
// Enable backlight and smooth PWM.
{ MIPI_DCS_WRITE_CONTROL_DISPLAY, 2, { 0x28, 0x0 } },
// Unlock Level 2 registers.
{ 0x05, 9, { 0x0, 0x0, 0xE2, 0x5A, 0x5A, 0x5A, 0x5A, 0x0, 0x0 } },
// Set registers offset and set PWM transition to 6 frames (100ms).
{ MIPI_DCS_PRIV_SM_SET_REG_OFFSET, 2, { 0x07, 0x0 } },
{ MIPI_DCS_PRIV_SM_SET_ELVSS, 2, { 0x06, 0x0 } },
// Relock Level 2 registers.
{ 0x05, 9, { 0x0, 0x0, 0xE2, 0x5A, 0x5A, 0xA5, 0xA5, 0x0, 0x0 } },
// MIPI_DCS_SET_BRIGHTNESS 0000: 0%. FF07: 100%.
{ 0x03, 7, { 0x00, 0x00, 0x51, 0x0, 0x0, 0x0, 0x0 } },
{
0xFF,
5,
},
};
struct init_cmd init_cmds_PANEL_AUO_A062TAN01[] = {
{ MIPI_DCS_EXIT_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
180,
},
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0xFF, 0x83, 0x94 } },
{
0xFF,
5,
},
{ MIPI_DCS_PRIV_SET_POWER_CONTROL, 6, { 0x48, 0x11, 0x71, 0x09, 0x32, 0x14 } },
};
struct init_cmd suspend_cmds_PANEL_AUO_A062TAN01[] = {
{
0xFF,
100,
},
{
0xFF,
5,
},
{ MIPI_DCS_ENTER_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
50,
},
};
struct init_cmd suspend_cmds_PANEL_AUO_A055TAN01[] = {
{
0xFF,
100,
},
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0xFF, 0x83, 0x94 } },
{
0xFF,
5,
},
{ MIPI_DCS_PRIV_SET_POWER_CONTROL, 10, { 0x48, 0x11, 0x71, 0x09, 0x32, 0x14, 0x71, 0x31, 0x4D, 0x11 } },
{
0xFF,
5,
},
{ MIPI_DCS_ENTER_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
50,
},
};
struct init_cmd init_cmds_PANEL_INL_P062CCA_AZ1[] = {
{ MIPI_DCS_EXIT_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
180,
},
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0xFF, 0x83, 0x94 } },
{
0xFF,
5,
},
{ MIPI_DCS_PRIV_SET_POWER_CONTROL, 6, { 0x48, 0x15, 0x75, 0x09, 0x32, 0x14 } },
};
struct init_cmd suspend_cmds_PANEL_INL_2J055IA_27A[] = {
{
0xFF,
100,
},
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0xFF, 0x83, 0x94 } },
{
0xFF,
5,
},
{ MIPI_DCS_PRIV_SET_POWER_CONTROL, 10, { 0x48, 0x15, 0x75, 0x09, 0x32, 0x14, 0x71, 0x31, 0x4D, 0x11 } },
{
0xFF,
5,
},
{ MIPI_DCS_ENTER_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
50,
},
};
struct init_cmd suspend_cmds_PANEL_SHP_LQ055T1SW10[] = {
{
0xFF,
100,
},
{ MIPI_DCS_PRIV_SET_EXTC, 3, { 0xFF, 0x83, 0x94 } },
{
0xFF,
5,
},
{ MIPI_DCS_PRIV_SET_POWER_CONTROL, 10, { 0x48, 0x13, 0x73, 0x09, 0x32, 0x24, 0x71, 0x31, 0x4C, 0x00 } },
{
0xFF,
5,
},
{ MIPI_DCS_ENTER_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
50,
},
};
struct init_cmd suspend_cmds_PANEL_SAM_AMS699VC01[] = {
{
0xFF,
100,
},
{ MIPI_DCS_ENTER_SLEEP_MODE, 2, { 0x00, 0x0 } },
{
0xFF,
120,
},
};
static inline struct nx_panel *to_nx_panel(struct drm_panel *panel)
{
return container_of(panel, struct nx_panel, base);
}
static void nx_panel_detect(struct nx_panel *nx)
{
int ret;
nx->init_cmds = NULL;
nx->suspend_cmds = NULL;
printk("nx_panel_detect");
memset(&(nx->display_id), 0, sizeof(nx->display_id));
ret = mipi_dsi_dcs_read(nx->dsi, MIPI_DCS_GET_DISPLAY_ID,
&(nx->display_id), sizeof(nx->display_id));
if (ret < 0) {
dev_err(&nx->dsi->dev, "failed to read panel ID: %d\n", ret);
} else {
dev_info(&nx->dsi->dev, "display ID[%d]: %04x\n",
ret, nx->display_id);
}
dev_info(&nx->dsi->dev,
"setting init sequence for ID %04x\n", nx->display_id);
switch (nx->display_id) {
case PANEL_JDI_XXX062M:
nx->init_cmds = init_cmds_PANEL_JDI_XXX062M;
break;
case PANEL_SAM_AMS699VC01:
nx->init_cmds = init_cmds_PANEL_SAM_AMS699VC01;
break;
case PANEL_INL_P062CCA_AZ1:
nx->init_cmds = init_cmds_PANEL_INL_P062CCA_AZ1;
break;
case PANEL_AUO_A062TAN01:
nx->init_cmds = init_cmds_PANEL_AUO_A062TAN01;
break;
case PANEL_INL_2J055IA_27A:
case PANEL_AUO_A055TAN01:
case PANEL_SHP_LQ055T1SW10:
default:
dev_info(&nx->dsi->dev, "using default init sequence\n");
nx->init_cmds = init_cmds_default;
break;
}
dev_info(&nx->dsi->dev,
"setting suspend sequence for ID %04x\n", nx->display_id);
switch (nx->display_id) {
case PANEL_JDI_XXX062M:
nx->suspend_cmds = suspend_cmds_PANEL_JDI_XXX062M;
break;
case PANEL_AUO_A062TAN01:
nx->suspend_cmds = suspend_cmds_PANEL_AUO_A062TAN01;
break;
case PANEL_INL_2J055IA_27A:
nx->suspend_cmds = suspend_cmds_PANEL_INL_2J055IA_27A;
break;
case PANEL_AUO_A055TAN01:
nx->suspend_cmds = suspend_cmds_PANEL_AUO_A055TAN01;
break;
case PANEL_SHP_LQ055T1SW10:
nx->suspend_cmds = suspend_cmds_PANEL_SHP_LQ055T1SW10;
break;
case PANEL_SAM_AMS699VC01:
nx->suspend_cmds = suspend_cmds_PANEL_SAM_AMS699VC01;
break;
case PANEL_INL_P062CCA_AZ1:
default:
dev_info(&nx->dsi->dev, "using default suspend sequence\n");
break;
}
msleep(20);
}
static int nx_mipi_dsi_dcs_cmds(struct init_cmd *cmds, struct nx_panel *nx)
{
int ret = 0;
while (cmds && cmds->length != -1) {
if (cmds->cmd == 0xFF)
msleep(cmds->length);
else {
ret = mipi_dsi_dcs_write(nx->dsi, cmds->cmd,
cmds->data, cmds->length);
if (ret < 0) {
dev_err(&nx->dsi->dev,
"failed to write dsi_cmd: %d error: %d\n",
cmds->cmd, ret);
return ret;
}
}
cmds++;
}
return ret;
}
static int nx_panel_init(struct nx_panel *nx)
{
struct mipi_dsi_device *dsi = nx->dsi;
struct device *dev = &nx->dsi->dev;
int ret;
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
printk("nx_panel_init");
ret = mipi_dsi_set_maximum_return_packet_size(dsi, 3);
if (ret < 0) {
dev_err(dev, "failed to set maximum return packet size: %d\n",
ret);
return ret;
}
nx_panel_detect(nx);
ret = nx_mipi_dsi_dcs_cmds(nx->init_cmds, nx);
if (ret < 0)
return ret;
ret = mipi_dsi_dcs_set_column_address(dsi, 0, nx->mode->hdisplay - 1);
if (ret < 0) {
dev_err(dev, "failed to set page address: %d\n", ret);
return ret;
}
ret = mipi_dsi_dcs_set_page_address(dsi, 0, nx->mode->vdisplay - 1);
if (ret < 0) {
dev_err(dev, "failed to set column address: %d\n", ret);
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 vblank tear on: %d\n", ret);
return ret;
}
ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT);
if (ret < 0) {
dev_err(dev, "failed to set pixel format: %d\n", ret);
return ret;
}
return 0;
}
static int nx_panel_enable(struct drm_panel *panel)
{
struct nx_panel *nx = to_nx_panel(panel);
if (nx->enabled)
return 0;
backlight_enable(nx->backlight);
nx->enabled = true;
return 0;
}
static int nx_panel_disable(struct drm_panel *panel)
{
struct nx_panel *nx = to_nx_panel(panel);
if (!nx->enabled)
return 0;
backlight_disable(nx->backlight);
nx->enabled = false;
return 0;
}
static int nx_panel_unprepare(struct drm_panel *panel)
{
struct nx_panel *nx = to_nx_panel(panel);
int ret;
if (!nx->prepared)
return 0;
nx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
ret = nx_mipi_dsi_dcs_cmds(nx->suspend_cmds, nx);
if (ret < 0)
dev_err(&nx->dsi->dev, "failed to write suspend cmds: %d\n",
ret);
if (nx->reset_gpio)
gpiod_set_value(nx->reset_gpio, 0);
msleep(10);
regulator_disable(nx->supply2);
msleep(10);
regulator_disable(nx->supply1);
nx->prepared = false;
return 0;
}
static int nx_panel_prepare(struct drm_panel *panel)
{
struct nx_panel *nx = to_nx_panel(panel);
struct device *dev = &nx->dsi->dev;
int ret;
printk("nx panel prepare");
if (nx->prepared)
return 0;
ret = regulator_enable(nx->supply1);
if (ret < 0)
return ret;
msleep(10);
ret = regulator_enable(nx->supply2);
if (ret < 0)
goto poweroff;
msleep(10);
if (nx->reset_gpio) {
gpiod_set_value(nx->reset_gpio, 0);
msleep(10);
gpiod_set_value(nx->reset_gpio, 1);
msleep(60);
}
nx->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
ret = nx_panel_init(nx);
if (ret < 0) {
dev_err(dev, "failed to init panel: %d\n", ret);
goto reset;
}
nx->prepared = true;
return 0;
reset:
if (nx->reset_gpio)
gpiod_set_value(nx->reset_gpio, 0);
regulator_disable(nx->supply2);
poweroff:
regulator_disable(nx->supply1);
return ret;
}
static const struct drm_display_mode default_mode = {
.clock = 78000,
.hdisplay = 720,
.hsync_start = 720 + 136,
.hsync_end = 720 + 136 + 72,
.htotal = 720 + 136 + 72 + 72,
.vdisplay = 1280,
.vsync_start = 1280 + 10,
.vsync_end = 1280 + 10 + 2,
.vtotal = 1280 + 10 + 1 + 9,
.width_mm = 77,
.height_mm = 137,
};
static int nx_panel_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
struct drm_display_mode *mode;
struct nx_panel *nx = to_nx_panel(panel);
struct device *dev = &nx->dsi->dev;
printk("nx panel get_modes");
mode = drm_mode_duplicate(connector->dev, &default_mode);
if (!mode) {
dev_err(dev, "failed to add mode %ux%ux@%u\n",
default_mode.hdisplay, default_mode.vdisplay,
drm_mode_vrefresh(&default_mode));
return -ENOMEM;
}
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);
connector->display_info.width_mm = default_mode.width_mm;
connector->display_info.height_mm = default_mode.height_mm;
return 1;
}
static const struct drm_panel_funcs nx_panel_funcs = {
.prepare = nx_panel_prepare,
.unprepare = nx_panel_unprepare,
.enable = nx_panel_enable,
.disable = nx_panel_disable,
.get_modes = nx_panel_get_modes,
};
static int nx_panel_add(struct nx_panel *nx)
{
struct device *dev = &nx->dsi->dev;
struct device_node *np;
printk("nx_panel_add");
nx->mode = &default_mode;
nx->supply1 = devm_regulator_get(dev, "vdd1");
if (IS_ERR(nx->supply1))
return PTR_ERR(nx->supply1);
nx->supply2 = devm_regulator_get(dev, "vdd2");
if (IS_ERR(nx->supply2))
return PTR_ERR(nx->supply2);
nx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(nx->reset_gpio)) {
dev_err(dev, "cannot get reset-gpios %ld\n",
PTR_ERR(nx->reset_gpio));
nx->reset_gpio = NULL;
} else {
gpiod_set_value(nx->reset_gpio, 0);
}
printk("backlight");
np = of_parse_phandle(dev->of_node, "backlight", 0);
if (np) {
nx->backlight = of_find_backlight_by_node(np);
of_node_put(np);
if (!nx->backlight)
return -EPROBE_DEFER;
}
printk("panel init");
drm_panel_init(&nx->base, &nx->dsi->dev, &nx_panel_funcs,
DRM_MODE_CONNECTOR_DSI);
printk("drm panel add");
drm_panel_add(&nx->base);
return 0;
}
static void nx_panel_del(struct nx_panel *nx)
{
if (nx->base.dev)
drm_panel_remove(&nx->base);
if (nx->backlight)
put_device(&nx->backlight->dev);
}
static int nx_panel_probe(struct mipi_dsi_device *dsi)
{
struct nx_panel *nx;
int ret;
dsi->lanes = 4;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
MIPI_DSI_CLOCK_NON_CONTINUOUS |
MIPI_DSI_MODE_NO_EOT_PACKET;
printk("nx_panel_probe");
nx = devm_kzalloc(&dsi->dev, sizeof(*nx), GFP_KERNEL);
if (!nx)
return -ENOMEM;
printk("set drvdata");
mipi_dsi_set_drvdata(dsi, nx);
nx->dsi = dsi;
printk("add panel");
ret = nx_panel_add(nx);
if (ret < 0)
return ret;
printk("dsi attach");
ret = mipi_dsi_attach(dsi);
if (ret < 0) {
nx_panel_del(nx);
return ret;
}
return 0;
}
static void nx_panel_remove(struct mipi_dsi_device *dsi)
{
struct nx_panel *nx = mipi_dsi_get_drvdata(dsi);
int ret;
printk("nx_panel_remove");
ret = nx_panel_disable(&nx->base);
if (ret < 0)
dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
nx_panel_del(nx);
}
static void nx_panel_shutdown(struct mipi_dsi_device *dsi)
{
struct nx_panel *nx = mipi_dsi_get_drvdata(dsi);
nx_panel_disable(&nx->base);
}
static const struct of_device_id nx_panel_of_match[] = {
{
.compatible = "nintendo,nx-dsi",
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, nx_panel_of_match);
static struct mipi_dsi_driver nx_panel_driver = {
.driver = {
.name = "panel-nx-dsi",
.of_match_table = nx_panel_of_match,
},
.probe = nx_panel_probe,
.remove = nx_panel_remove,
.shutdown = nx_panel_shutdown,
};
module_mipi_dsi_driver(nx_panel_driver);
MODULE_AUTHOR("SwtcR <swtcr0@gmail.com>");
MODULE_DESCRIPTION("Nintendo Switch DSI (720x1280) panel driver");
MODULE_LICENSE("GPL v2");

View File

@@ -1378,6 +1378,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
{ .compatible = "nvidia,tegra132-dsi", },
{ .compatible = "nvidia,tegra210-dc", },
{ .compatible = "nvidia,tegra210-dsi", },
{ .compatible = "nvidia,tegra210b01-dsi", },
{ .compatible = "nvidia,tegra210-sor", },
{ .compatible = "nvidia,tegra210-sor1", },
{ .compatible = "nvidia,tegra210-vic", },

View File

@@ -52,6 +52,21 @@ to_dsi_state(struct drm_connector_state *state)
return container_of(state, struct tegra_dsi_state, base);
}
/*
* remap of registers revised in Tegra210B01
*/
struct dsi_regmap {
int init_seq_data_15;
int slew_impedance[4];
int preemphasis;
int bias;
int ganged_mode_control;
int ganged_mode_start;
int ganged_mode_size;
int dbg_regs_cnt;
struct debugfs_reg32 dbg_regs_ext[16];
};
struct tegra_dsi {
struct host1x_client client;
struct tegra_output output;
@@ -81,6 +96,8 @@ struct tegra_dsi {
/* for ganged-mode support */
struct tegra_dsi *master;
struct tegra_dsi *slave;
const struct dsi_regmap *regmap;
};
static inline struct tegra_dsi *
@@ -122,7 +139,7 @@ static inline void tegra_dsi_writel(struct tegra_dsi *dsi, u32 value,
#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
static const struct debugfs_reg32 tegra_dsi_regs[] = {
static const struct debugfs_reg32 tegra_dsi_regs_common[] = {
DEBUGFS_REG32(DSI_INCR_SYNCPT),
DEBUGFS_REG32(DSI_INCR_SYNCPT_CONTROL),
DEBUGFS_REG32(DSI_INCR_SYNCPT_ERROR),
@@ -181,19 +198,6 @@ static const struct debugfs_reg32 tegra_dsi_regs[] = {
DEBUGFS_REG32(DSI_PAD_CONTROL_2),
DEBUGFS_REG32(DSI_PAD_CONTROL_3),
DEBUGFS_REG32(DSI_PAD_CONTROL_4),
DEBUGFS_REG32(DSI_GANGED_MODE_CONTROL),
DEBUGFS_REG32(DSI_GANGED_MODE_START),
DEBUGFS_REG32(DSI_GANGED_MODE_SIZE),
DEBUGFS_REG32(DSI_RAW_DATA_BYTE_COUNT),
DEBUGFS_REG32(DSI_ULTRA_LOW_POWER_CONTROL),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_8),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_9),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_10),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_11),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_12),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_13),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_14),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_15),
};
static int tegra_dsi_show_regs(struct seq_file *s, void *data)
@@ -212,10 +216,17 @@ static int tegra_dsi_show_regs(struct seq_file *s, void *data)
goto unlock;
}
for (i = 0; i < ARRAY_SIZE(tegra_dsi_regs); i++) {
unsigned int offset = tegra_dsi_regs[i].offset;
for (i = 0; i < ARRAY_SIZE(tegra_dsi_regs_common); i++) {
unsigned int offset = tegra_dsi_regs_common[i].offset;
seq_printf(s, "%-32s %#05x %08x\n", tegra_dsi_regs[i].name,
seq_printf(s, "%-32s %#05x %08x\n", tegra_dsi_regs_common[i].name,
offset, tegra_dsi_readl(dsi, offset));
}
for (i = 0; i < dsi->regmap->dbg_regs_cnt; i++) {
unsigned int offset = dsi->regmap->dbg_regs_ext[i].offset;
seq_printf(s, "%-32s %#05x %08x\n", dsi->regmap->dbg_regs_ext[i].name,
offset, tegra_dsi_readl(dsi, offset));
}
@@ -446,11 +457,11 @@ static void tegra_dsi_ganged_enable(struct tegra_dsi *dsi, unsigned int start,
{
u32 value;
tegra_dsi_writel(dsi, start, DSI_GANGED_MODE_START);
tegra_dsi_writel(dsi, size << 16 | size, DSI_GANGED_MODE_SIZE);
tegra_dsi_writel(dsi, start, dsi->regmap->ganged_mode_start);
tegra_dsi_writel(dsi, size << 16 | size, dsi->regmap->ganged_mode_size);
value = DSI_GANGED_MODE_CONTROL_ENABLE;
tegra_dsi_writel(dsi, value, DSI_GANGED_MODE_CONTROL);
tegra_dsi_writel(dsi, value, dsi->regmap->ganged_mode_control);
}
static void tegra_dsi_enable(struct tegra_dsi *dsi)
@@ -653,9 +664,9 @@ static void tegra_dsi_video_disable(struct tegra_dsi *dsi)
static void tegra_dsi_ganged_disable(struct tegra_dsi *dsi)
{
tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_START);
tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_SIZE);
tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL);
tegra_dsi_writel(dsi, 0, dsi->regmap->ganged_mode_start);
tegra_dsi_writel(dsi, 0, dsi->regmap->ganged_mode_size);
tegra_dsi_writel(dsi, 0, dsi->regmap->ganged_mode_control);
}
static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
@@ -671,7 +682,7 @@ static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
{
u32 value;
int err;
int err, i;
/*
* XXX Is this still needed? The module reset is deasserted right
@@ -679,21 +690,29 @@ static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
*/
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0);
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1);
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_2);
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_3);
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_4);
for (i = 0; i < ARRAY_SIZE(dsi->regmap->slew_impedance); i++) {
if (dsi->regmap->slew_impedance[i])
tegra_dsi_writel(dsi, 0, dsi->regmap->slew_impedance[i]);
}
/* start calibration */
tegra_dsi_pad_enable(dsi);
/* do not set padctl 2 slew by default */
if (of_property_read_bool(dsi->dev->of_node, "nvidia,slew-enable")) {
value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) |
DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) |
DSI_PAD_OUT_CLK(0x0);
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_2);
}
value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
value = tegra_dsi_readl(dsi, dsi->regmap->preemphasis);
value |= DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);
tegra_dsi_writel(dsi, value, dsi->regmap->preemphasis);
tegra_dsi_writel(dsi, 0, dsi->regmap->bias);
err = tegra_mipi_start_calibration(dsi->mipi);
if (err < 0)
@@ -1643,6 +1662,12 @@ static int tegra_dsi_probe(struct platform_device *pdev)
goto remove;
}
dsi->regmap = of_device_get_match_data(&pdev->dev);
if (IS_ERR(dsi->regmap)) {
err = PTR_ERR(dsi->regmap);
goto remove;
}
dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node);
if (IS_ERR(dsi->mipi)) {
err = PTR_ERR(dsi->mipi);
@@ -1698,11 +1723,87 @@ static void tegra_dsi_remove(struct platform_device *pdev)
tegra_mipi_free(dsi->mipi);
}
static const struct dsi_regmap tegra_dsi_regmap = {
.init_seq_data_15 = DSI_INIT_SEQ_DATA_15,
.slew_impedance = { DSI_PAD_CONTROL_2 },
.preemphasis = DSI_PAD_CONTROL_3,
.bias = DSI_PAD_CONTROL_4,
.ganged_mode_control = DSI_GANGED_MODE_CONTROL,
.ganged_mode_start = DSI_GANGED_MODE_START,
.ganged_mode_size = DSI_GANGED_MODE_SIZE,
.dbg_regs_cnt = 13,
.dbg_regs_ext = {
DEBUGFS_REG32(DSI_GANGED_MODE_CONTROL),
DEBUGFS_REG32(DSI_GANGED_MODE_START),
DEBUGFS_REG32(DSI_GANGED_MODE_SIZE),
DEBUGFS_REG32(DSI_RAW_DATA_BYTE_COUNT),
DEBUGFS_REG32(DSI_ULTRA_LOW_POWER_CONTROL),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_8),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_9),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_10),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_11),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_12),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_13),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_14),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_15),
},
};
static const struct dsi_regmap tegra_dsi_regmap_b01 = {
.init_seq_data_15 = DSI_INIT_SEQ_DATA_15_B01,
.slew_impedance = {
DSI_PAD_CONTROL_2,
DSI_PAD_CONTROL_3,
DSI_PAD_CONTROL_4,
DSI_PAD_CONTROL_5_B01,
},
.preemphasis = DSI_PAD_CONTROL_6_B01,
.bias = DSI_PAD_CONTROL_7_B01,
.ganged_mode_control = DSI_GANGED_MODE_CONTROL_B01,
.ganged_mode_start = DSI_GANGED_MODE_START_B01,
.ganged_mode_size = DSI_GANGED_MODE_SIZE_B01,
.dbg_regs_cnt = 16,
.dbg_regs_ext = {
DEBUGFS_REG32(DSI_PAD_CONTROL_5_B01),
DEBUGFS_REG32(DSI_PAD_CONTROL_6_B01),
DEBUGFS_REG32(DSI_PAD_CONTROL_7_B01),
DEBUGFS_REG32(DSI_GANGED_MODE_CONTROL_B01),
DEBUGFS_REG32(DSI_GANGED_MODE_START_B01),
DEBUGFS_REG32(DSI_GANGED_MODE_SIZE_B01),
DEBUGFS_REG32(DSI_RAW_DATA_BYTE_COUNT_B01),
DEBUGFS_REG32(DSI_ULTRA_LOW_POWER_CONTROL_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_8_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_9_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_10_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_11_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_12_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_13_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_14_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_15_B01),
},
};
static const struct of_device_id tegra_dsi_of_match[] = {
{ .compatible = "nvidia,tegra210-dsi", },
{ .compatible = "nvidia,tegra132-dsi", },
{ .compatible = "nvidia,tegra124-dsi", },
{ .compatible = "nvidia,tegra114-dsi", },
{
.compatible = "nvidia,tegra210b01-dsi",
.data = &tegra_dsi_regmap_b01
},
{
.compatible = "nvidia,tegra210-dsi",
.data = &tegra_dsi_regmap
},
{
.compatible = "nvidia,tegra132-dsi",
.data = &tegra_dsi_regmap
},
{
.compatible = "nvidia,tegra124-dsi",
.data = &tegra_dsi_regmap
},
{
.compatible = "nvidia,tegra114-dsi",
.data = &tegra_dsi_regmap
},
{ },
};
MODULE_DEVICE_TABLE(of, tegra_dsi_of_match);

View File

@@ -130,6 +130,24 @@
#define DSI_INIT_SEQ_DATA_14 0x5e
#define DSI_INIT_SEQ_DATA_15 0x5f
// Tegra210B01 has a revised set of regs
#define DSI_PAD_CONTROL_5_B01 0x53
#define DSI_PAD_CONTROL_6_B01 0x54
#define DSI_PAD_CONTROL_7_B01 0x55
#define DSI_GANGED_MODE_CONTROL_B01 0x56
#define DSI_GANGED_MODE_START_B01 0x57
#define DSI_GANGED_MODE_SIZE_B01 0x58
#define DSI_RAW_DATA_BYTE_COUNT_B01 0x59
#define DSI_ULTRA_LOW_POWER_CONTROL_B01 0x5a
#define DSI_INIT_SEQ_DATA_8_B01 0x5b
#define DSI_INIT_SEQ_DATA_9_B01 0x5c
#define DSI_INIT_SEQ_DATA_10_B01 0x5d
#define DSI_INIT_SEQ_DATA_11_B01 0x5e
#define DSI_INIT_SEQ_DATA_12_B01 0x5f
#define DSI_INIT_SEQ_DATA_13_B01 0x60
#define DSI_INIT_SEQ_DATA_14_B01 0x61
#define DSI_INIT_SEQ_DATA_15_B01 0x62
/*
* pixel format as used in the DSI_CONTROL_FORMAT field
*/

View File

@@ -516,6 +516,9 @@ static const struct of_device_id tegra186_emc_of_match[] = {
#if defined(CONFIG_ARCH_TEGRA_186_SOC)
{ .compatible = "nvidia,tegra186-emc" },
#endif
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
{ .compatible = "nvidia,tegra210b01-emc" },
#endif
#if defined(CONFIG_ARCH_TEGRA_194_SOC)
{ .compatible = "nvidia,tegra194-emc" },
#endif

View File

@@ -1846,6 +1846,15 @@ static void tegra_pcie_disable_interrupts(struct tegra_pcie *pcie)
afi_writel(pcie, value, AFI_INTR_MASK);
}
static void update_rp_lanes(struct tegra_pcie *pcie, u32 lanes)
{
struct tegra_pcie_port *port = NULL;
list_for_each_entry(port, &pcie->ports, list)
port->lanes = (lanes >> (port->index << 3)) & 0xFF;
}
static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
u32 *xbar)
{
@@ -1874,6 +1883,21 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
"switching to default 2x1, 1x1, 1x1 "
"configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211;
update_rp_lanes(pcie, 0x010102);
return 0;
}
} else if (of_device_is_compatible(np, "nvidia,tegra210b01-pcie")) {
switch (lanes) {
case 0x0104:
dev_info(pcie->dev, "4x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
return 0;
default:
dev_info(pcie->dev, "wrong configuration updated in DT, "
"switching to default 4x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
update_rp_lanes(pcie, 0x0104);
return 0;
}
} else if (of_device_is_compatible(np, "nvidia,tegra124-pcie") ||
@@ -1888,6 +1912,13 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
dev_info(dev, "2x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1;
return 0;
default:
dev_info(pcie->dev, "wrong configuration updated in DT, "
"switching to default 4x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
update_rp_lanes(pcie, 0x0104);
return 0;
}
} else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
switch (lanes) {
@@ -1905,6 +1936,14 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
dev_info(dev, "4x1, 1x2 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411;
return 0;
default:
dev_info(dev, "wrong configuration updated in DT, "
"switching to default 4x1, 1x2 "
"configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411;
update_rp_lanes(pcie, 0x010104);
return 0;
}
} else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
switch (lanes) {
@@ -1917,6 +1956,14 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
dev_info(dev, "dual-mode configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
return 0;
default:
dev_info(dev, "wrong configuration updated in DT, "
"switching to default dual-mode "
"configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
update_rp_lanes(pcie, 0x000202);
return 0;
}
}
@@ -2010,7 +2057,8 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
pcie->supplies[i++].supply = "hvdd-pex-pll";
pcie->supplies[i++].supply = "hvdd-pex";
pcie->supplies[i++].supply = "vddio-pexctl-aud";
} else if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
} else if (of_device_is_compatible(np, "nvidia,tegra210-pcie") ||
of_device_is_compatible(np, "nvidia,tegra210b01-pcie")) {
pcie->num_supplies = 3;
pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
@@ -2490,6 +2538,40 @@ static const struct tegra_pcie_soc tegra210_pcie = {
},
};
static const struct tegra_pcie_soc tegra210b01_pcie = {
.num_ports = 2,
.ports = tegra20_pcie_ports,
.msi_base_shift = 8,
.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
.pads_refclk_cfg0 = 0x90b890b8,
/* FC threshold is bit[25:18] */
.update_fc_threshold = 0x01800000,
.has_pex_clkreq_en = true,
.has_pex_bias_ctrl = true,
.has_intr_prsnt_sense = true,
.has_cml_clk = true,
.has_gen2 = true,
.force_pca_enable = true,
.program_uphy = true,
.program_deskew_time = true,
.update_fc_timer = true,
.has_cache_bars = false,
.ectl = {
.regs = {
.rp_ectl_2_r1 = 0x0000000f,
.rp_ectl_4_r1 = 0x00000067,
.rp_ectl_5_r1 = 0x55010000,
.rp_ectl_6_r1 = 0x00000001,
.rp_ectl_2_r2 = 0x0000008f,
.rp_ectl_4_r2 = 0x000000c7,
.rp_ectl_5_r2 = 0x55010000,
.rp_ectl_6_r2 = 0x00000001,
},
.enable = true,
},
};
static const struct tegra_pcie_port_soc tegra186_pcie_ports[] = {
{ .pme.turnoff_bit = 0, .pme.ack_bit = 5 },
{ .pme.turnoff_bit = 8, .pme.ack_bit = 10 },
@@ -2522,6 +2604,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
static const struct of_device_id tegra_pcie_of_match[] = {
{ .compatible = "nvidia,tegra186-pcie", .data = &tegra186_pcie },
{ .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie },
{ .compatible = "nvidia,tegra210b01-pcie", .data = &tegra210b01_pcie },
{ .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie },
{ .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie },
{ .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie },

View File

@@ -525,6 +525,8 @@ static void tegra_xusb_port_release(struct device *dev)
{
struct tegra_xusb_port *port = to_tegra_xusb_port(dev);
printk("release\n");
if (port->ops->release)
port->ops->release(port);
}
@@ -541,19 +543,23 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
{
int err;
printk("init list\n");
INIT_LIST_HEAD(&port->list);
port->padctl = padctl;
port->index = index;
printk("init device\n");
device_initialize(&port->dev);
port->dev.type = &tegra_xusb_port_type;
port->dev.of_node = of_node_get(np);
port->dev.parent = padctl->dev;
printk("set name\n");
err = dev_set_name(&port->dev, "%s-%u", name, index);
if (err < 0)
goto put_device;
printk("device add\n");
err = device_add(&port->dev);
if (err < 0)
goto put_device;
@@ -561,6 +567,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
return 0;
put_device:
printk("put device\n");
put_device(&port->dev);
return err;
}
@@ -969,6 +976,7 @@ static int tegra_xusb_usb3_port_parse_dt(struct tegra_xusb_usb3_port *usb3)
u32 value;
int err;
printk("check usb2-companion\n");
err = of_property_read_u32(np, "nvidia,usb2-companion", &value);
if (err < 0) {
dev_err(&port->dev, "failed to read port: %d\n", err);
@@ -1004,6 +1012,7 @@ static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl,
* port is unusable. But it is valid to configure only a single port,
* hence return 0 instead of an error to allow ports to be optional.
*/
printk("find port node usb3\n");
np = tegra_xusb_find_port_node(padctl, "usb3", index);
if (!np || !of_device_is_available(np))
goto out;
@@ -1014,6 +1023,7 @@ static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl,
goto out;
}
printk("xusb port init\n");
err = tegra_xusb_port_init(&usb3->base, padctl, np, "usb3", index);
if (err < 0)
goto out;
@@ -1026,6 +1036,7 @@ static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl,
goto out;
}
printk("xusb usb3 port parse dt\n");
err = tegra_xusb_usb3_port_parse_dt(usb3);
if (err < 0) {
tegra_xusb_port_unregister(&usb3->base);
@@ -1118,24 +1129,28 @@ static int tegra_xusb_setup_ports(struct tegra_xusb_padctl *padctl)
mutex_lock(&padctl->lock);
for (i = 0; i < padctl->soc->ports.usb2.count; i++) {
printk("add usb2 port %d\n", i);
err = tegra_xusb_add_usb2_port(padctl, i);
if (err < 0)
goto remove_ports;
}
for (i = 0; i < padctl->soc->ports.ulpi.count; i++) {
printk("add ulpi port %d\n", i);
err = tegra_xusb_add_ulpi_port(padctl, i);
if (err < 0)
goto remove_ports;
}
for (i = 0; i < padctl->soc->ports.hsic.count; i++) {
printk("add hsic port %d\n", i);
err = tegra_xusb_add_hsic_port(padctl, i);
if (err < 0)
goto remove_ports;
}
for (i = 0; i < padctl->soc->ports.usb3.count; i++) {
printk("add usb3 port %d\n", i);
err = tegra_xusb_add_usb3_port(padctl, i);
if (err < 0)
goto remove_ports;
@@ -1143,10 +1158,12 @@ static int tegra_xusb_setup_ports(struct tegra_xusb_padctl *padctl)
if (padctl->soc->need_fake_usb3_port) {
for (i = 0; i < padctl->soc->ports.usb2.count; i++) {
printk("checking usb2 port %d\n", i);
usb2 = tegra_xusb_find_usb2_port(padctl, i);
if (!usb2)
continue;
printk("update usb3 fake port %d\n", i);
err = tegra_xusb_update_usb3_fake_port(usb2);
if (err < 0)
goto remove_ports;
@@ -1154,12 +1171,14 @@ static int tegra_xusb_setup_ports(struct tegra_xusb_padctl *padctl)
}
list_for_each_entry(port, &padctl->ports, list) {
printk("enable port\n");
err = port->ops->enable(port);
if (err < 0)
dev_err(padctl->dev, "failed to enable port %s: %d\n",
dev_name(&port->dev), err);
}
printk("unlock\n");
goto unlock;
remove_ports:

View File

@@ -4552,6 +4552,37 @@ int regulator_get_voltage(struct regulator *regulator)
}
EXPORT_SYMBOL_GPL(regulator_get_voltage);
/**
* regulator_get_constraint_voltages - get platform specific constraint voltage,
* @regulator: regulator source
* @min_uV: Minimum microvolts.
* @max_uV: Maximum microvolts.
*
* This returns the current regulator voltage in uV.
*
* NOTE: If the regulator is disabled it will return the voltage value. This
* function should not be used to determine regulator state.
*/
int regulator_get_constraint_voltages(struct regulator *regulator,
int *min_uV, int *max_uV)
{
struct regulator_dev *rdev = regulator->rdev;
if (rdev->desc && rdev->desc->fixed_uV && rdev->desc->n_voltages == 1) {
*min_uV = rdev->desc->fixed_uV;
*max_uV = rdev->desc->fixed_uV;
return 0;
}
if (rdev->constraints) {
*min_uV = rdev->constraints->min_uV;
*max_uV = rdev->constraints->max_uV;
return 0;
}
return -EINVAL;
}
EXPORT_SYMBOL_GPL(regulator_get_constraint_voltages);
/**
* regulator_set_current_limit - set regulator output current limit
* @regulator: regulator source

View File

@@ -25,7 +25,12 @@
#include "fuse.h"
struct tegra_sku_info tegra_sku_info;
struct tegra_sku_info tegra_sku_info = {
.cpu_iddq_value = -ENOTSUPP,
.gpu_iddq_value = -ENOTSUPP,
.soc_iddq_value = -ENOTSUPP,
.speedo_rev = -ENOTSUPP,
};
EXPORT_SYMBOL(tegra_sku_info);
static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
@@ -117,7 +122,7 @@ static void tegra_fuse_restore(void *base)
static void tegra_fuse_print_sku_info(struct tegra_sku_info *tegra_sku_info)
{
pr_info("Tegra Revision: %s SKU: %d CPU Process: %d SoC Process: %d\n",
pr_info("Tegra Revision: %s SKU: 0x%x CPU Process: %d SoC Process: %d\n",
tegra_revision_name[tegra_sku_info->revision],
tegra_sku_info->sku_id, tegra_sku_info->cpu_process_id,
tegra_sku_info->soc_process_id);
@@ -366,6 +371,33 @@ int tegra_fuse_readl(unsigned long offset, u32 *value)
}
EXPORT_SYMBOL(tegra_fuse_readl);
int tegra_fuse_get_cpu_iddq(void)
{
if (!fuse->soc || !fuse->base)
return -ENODEV;
return tegra_sku_info.cpu_iddq_value;
}
EXPORT_SYMBOL(tegra_fuse_get_cpu_iddq);
int tegra_fuse_get_gpu_iddq(void)
{
if (!fuse->soc || !fuse->base)
return -ENODEV;
return tegra_sku_info.gpu_iddq_value;
}
EXPORT_SYMBOL(tegra_fuse_get_gpu_iddq);
int tegra_fuse_get_soc_iddq(void)
{
if (!fuse->soc || !fuse->base)
return -ENODEV;
return tegra_sku_info.soc_iddq_value;
}
EXPORT_SYMBOL(tegra_fuse_get_soc_iddq);
static void tegra_enable_fuse_clk(void __iomem *base)
{
u32 reg;

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2013-2016, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/device.h>
@@ -111,6 +111,16 @@ void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)
THRESHOLD_INDEX_COUNT);
sku_info->cpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_0);
/* GPU Speedo is stored in CPU_SPEEDO_2 */
sku_info->gpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_2);
soc_speedo_0_value = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
sku_info->cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
sku_info->soc_iddq_value = tegra_fuse_read_early(FUSE_SOC_IDDQ);
sku_info->gpu_iddq_value = tegra_fuse_read_early(FUSE_GPU_IDDQ);
if (sku_info->cpu_speedo_value == 0) {
pr_warn("Tegra Warning: Speedo value not fused.\n");
WARN_ON(1);
@@ -123,8 +133,6 @@ void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)
rev_sku_to_speedo_ids(sku_info, &threshold);
sku_info->cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
for (i = 0; i < GPU_PROCESS_CORNERS; i++)
if (sku_info->gpu_speedo_value <
gpu_process_speedos[threshold][i])

View File

@@ -1,11 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2013-2017, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/bug.h>
#include <linux/of.h>
#include <soc/tegra/fuse.h>
@@ -29,22 +30,26 @@
enum {
THRESHOLD_INDEX_0,
THRESHOLD_INDEX_1,
THRESHOLD_INDEX_2,
THRESHOLD_INDEX_COUNT,
};
static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
{ 2119, UINT_MAX },
{ 2119, UINT_MAX },
{ 1650, UINT_MAX },
};
static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = {
{ UINT_MAX, UINT_MAX },
{ UINT_MAX, UINT_MAX },
{ UINT_MAX, UINT_MAX },
};
static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
{ 1950, 2100, UINT_MAX },
{ 1950, 2100, UINT_MAX },
{ 1950, 2073, UINT_MAX },
{ UINT_MAX, UINT_MAX, UINT_MAX },
{ 1598, 1709, UINT_MAX },
};
static u8 __init get_speedo_revision(void)
@@ -54,66 +59,154 @@ static u8 __init get_speedo_revision(void)
tegra_fuse_read_spare(2) << 0;
}
static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
static void __init rev_t210sku_to_speedo_ids(struct tegra_sku_info *sku_info,
u8 speedo_rev, int *threshold)
{
int sku = sku_info->sku_id;
int rev = sku_info->revision;
bool a02 = (rev != TEGRA_REVISION_A01) &&
(rev != TEGRA_REVISION_UNKNOWN);
bool vcm31_sku = false;
bool always_on = false;
/* Assign to default */
sku_info->cpu_speedo_id = 0;
sku_info->soc_speedo_id = 0;
sku_info->gpu_speedo_id = 0;
sku_info->ucm = TEGRA_UCM1;
*threshold = THRESHOLD_INDEX_0;
#ifdef CONFIG_OF
vcm31_sku = of_property_read_bool(of_chosen, "nvidia,t210-vcm31-sku");
always_on = of_property_read_bool(of_chosen,
"nvidia,tegra-always-on-personality");
#endif
if (sku_info->revision >= TEGRA_REVISION_A02) {
switch (sku) {
case 0x00: /* Engineering SKU */
case 0x01: /* Engineering SKU */
case 0x13:
if (a02) {
sku_info->cpu_speedo_id = 5;
sku_info->gpu_speedo_id = 2;
break;
}
/* fall through for a01 */
fallthrough;
case 0x07:
case 0x17:
case 0x1F:
if (vcm31_sku && sku == 0x17) {
sku_info->cpu_speedo_id = 4;
sku_info->soc_speedo_id = 1;
sku_info->gpu_speedo_id = 4;
*threshold = THRESHOLD_INDEX_1;
break;
}
if (a02) {
sku_info->cpu_speedo_id = 7;
sku_info->gpu_speedo_id = 2;
if (always_on) {
sku_info->cpu_speedo_id = 8;
sku_info->ucm = TEGRA_UCM2;
}
break;
}
/* fall through for a01 */
fallthrough;
case 0x27:
if (a02) {
sku_info->cpu_speedo_id = 1;
sku_info->gpu_speedo_id = 2;
break;
}
sku_info->gpu_speedo_id = 1;
break;
case 0x57:
sku_info->cpu_speedo_id = 4;
sku_info->soc_speedo_id = 1;
sku_info->gpu_speedo_id = 4;
*threshold = THRESHOLD_INDEX_1;
break;
case 0x83:
if (a02) {
sku_info->cpu_speedo_id = 3;
sku_info->gpu_speedo_id = 3;
break;
}
/* fall through for a01 */
fallthrough;
case 0x87:
if (a02) {
sku_info->cpu_speedo_id = 2;
sku_info->gpu_speedo_id = 1;
break;
}
/* fall through for a01 */
fallthrough;
case 0x8F:
sku_info->soc_speedo_id = 2;
if (a02 && always_on) {
sku_info->cpu_speedo_id = 9;
sku_info->gpu_speedo_id = 2;
sku_info->ucm = TEGRA_UCM2;
break;
}
fallthrough;
default:
pr_err("Tegra210: unknown revision 2 or newer SKU %#04x\n", sku);
pr_err("Tegra210: invalid combination of SKU/revision/mode:\n");
pr_err("Tegra210: SKU %#04x, rev %d, vcm31 %d, always_on %d\n",
sku, rev, vcm31_sku, always_on);
/* Using the default for the error case */
break;
}
} else if (sku == 0x00 || sku == 0x01 || sku == 0x07 || sku == 0x13 || sku == 0x17) {
sku_info->gpu_speedo_id = 1;
} else {
pr_err("Tegra210: unknown SKU %#04x\n", sku);
}
static void __init rev_t210b01sku_to_speedo_ids(struct tegra_sku_info *sku_info,
u8 speedo_rev, int *threshold)
{
int sku = sku_info->sku_id;
int rev = sku_info->revision;
/* Assign to default */
sku_info->cpu_speedo_id = 0;
sku_info->soc_speedo_id = 0;
sku_info->gpu_speedo_id = 1; /* T210b01 GPC PLL default NA mode */
sku_info->ucm = TEGRA_UCM1;
*threshold = THRESHOLD_INDEX_2;
switch (sku) {
case 0x00: /* Engineering SKU */
case 0x01: /* Engineering SKU */
case 0x83:
break;
case 0x87:
sku_info->cpu_speedo_id = 3;
break;
default:
pr_err("Tegra210b01: invalid combination of SKU/revision/mode:\n");
pr_err("Tegra210b01: SKU %#04x, rev %d\n", sku, rev);
/* Using the default for the error case */
break;
}
}
static bool __init is_t210b01_sku(struct tegra_sku_info *sku_info)
{
u8 chip = tegra_get_chip_id();
if (chip == TEGRA210 && sku_info->revision == TEGRA_REVISION_B01)
return true;
return false;
}
static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
u8 speedo_rev, int *threshold)
{
if (is_t210b01_sku(sku_info))
rev_t210b01sku_to_speedo_ids(sku_info, speedo_rev, threshold);
else
rev_t210sku_to_speedo_ids(sku_info, speedo_rev, threshold);
}
static int get_process_id(int value, const u32 *speedos, unsigned int num)
{
unsigned int i;
@@ -129,7 +222,7 @@ void __init tegra210_init_speedo_data(struct tegra_sku_info *sku_info)
{
int cpu_speedo[3], soc_speedo[3];
unsigned int index;
u8 speedo_revision;
u8 speedo_revision = 0;
BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
THRESHOLD_INDEX_COUNT);
@@ -145,28 +238,41 @@ void __init tegra210_init_speedo_data(struct tegra_sku_info *sku_info)
soc_speedo[0] = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
soc_speedo[1] = tegra_fuse_read_early(FUSE_SOC_SPEEDO_1);
soc_speedo[2] = tegra_fuse_read_early(FUSE_SOC_SPEEDO_2);
soc_speedo[2] = tegra_fuse_read_early(FUSE_CPU_SPEEDO_2);
sku_info->cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ) * 4;
sku_info->soc_iddq_value = tegra_fuse_read_early(FUSE_SOC_IDDQ) * 4;
sku_info->gpu_iddq_value = tegra_fuse_read_early(FUSE_GPU_IDDQ) * 5;
/*
* Determine CPU, GPU and SoC speedo values depending on speedo fusing
* revision. Note that GPU speedo value is fused in CPU_SPEEDO_2.
*/
speedo_revision = get_speedo_revision();
pr_info("Speedo Revision %u\n", speedo_revision);
sku_info->speedo_rev = speedo_revision;
if (is_t210b01_sku(sku_info)) {
sku_info->cpu_speedo_value = cpu_speedo[0];
sku_info->gpu_speedo_value = cpu_speedo[2];
sku_info->soc_speedo_value = soc_speedo[0];
} else {
if (speedo_revision >= 3) {
sku_info->cpu_speedo_value = cpu_speedo[0];
sku_info->gpu_speedo_value = cpu_speedo[2];
sku_info->soc_speedo_value = soc_speedo[0];
} else if (speedo_revision == 2) {
sku_info->cpu_speedo_value = (-1938 + (1095 * cpu_speedo[0] / 100)) / 10;
sku_info->gpu_speedo_value = (-1662 + (1082 * cpu_speedo[2] / 100)) / 10;
sku_info->soc_speedo_value = ( -705 + (1037 * soc_speedo[0] / 100)) / 10;
sku_info->cpu_speedo_value =
(-1938 + (1095 * cpu_speedo[0] / 100)) / 10;
sku_info->gpu_speedo_value =
(-1662 + (1082 * cpu_speedo[2] / 100)) / 10;
sku_info->soc_speedo_value =
(-705 + (1037 * soc_speedo[0] / 100)) / 10;
} else {
sku_info->cpu_speedo_value = 2100;
sku_info->gpu_speedo_value = cpu_speedo[2] - 75;
sku_info->soc_speedo_value = 1900;
}
}
if ((sku_info->cpu_speedo_value <= 0) ||
(sku_info->gpu_speedo_value <= 0) ||
@@ -189,6 +295,13 @@ void __init tegra210_init_speedo_data(struct tegra_sku_info *sku_info)
soc_process_speedos[index],
SOC_PROCESS_CORNERS);
pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",
sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
pr_info("Tegra Speedo/IDDQ fuse revision %u\n", speedo_revision);
pr_info("Tegra: CPU Speedo ID %d, SoC Speedo ID %d, GPU Speedo ID %d\n",
sku_info->cpu_speedo_id, sku_info->soc_speedo_id, sku_info->gpu_speedo_id);
pr_info("Tegra: CPU Process ID %d, SoC Process ID %d, GPU Process ID %d\n",
sku_info->cpu_process_id, sku_info->soc_process_id, sku_info->gpu_process_id);
pr_info("Tegra: CPU Speedo Value %d, SoC Speedo Value %d, GPU Speedo Value %d\n",
sku_info->cpu_speedo_value, sku_info->soc_speedo_value, sku_info->gpu_speedo_value);
pr_info("Tegra: CPU IDDQ Value %d, SoC IDDQ Value %d, GPU IDDQ Value %d\n",
sku_info->cpu_iddq_value, sku_info->soc_iddq_value, sku_info->gpu_iddq_value);
}

View File

@@ -133,11 +133,15 @@ static const struct of_device_id apbmisc_match[] __initconst = {
void __init tegra_init_revision(void)
{
u8 chip_id, minor_rev;
u8 chip_id, major_rev, minor_rev;
chip_id = tegra_get_chip_id();
major_rev = tegra_get_major_rev();
minor_rev = tegra_get_minor_rev();
if (major_rev > 1) {
tegra_sku_info.revision = TEGRA_REVISION_B01;
} else {
switch (minor_rev) {
case 1:
tegra_sku_info.revision = TEGRA_REVISION_A01;
@@ -158,6 +162,7 @@ void __init tegra_init_revision(void)
default:
tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN;
}
}
tegra_sku_info.sku_id = tegra_fuse_read_early(FUSE_SKU_INFO);
tegra_sku_info.platform = tegra_get_platform();

View File

@@ -1457,7 +1457,7 @@ static int tegra_powergate_init(struct tegra_pmc *pmc,
if (!np)
return 0;
for_each_child_of_node_scoped(np, child) {
for_each_available_child_of_node_scoped(np, child) {
err = tegra_powergate_add(pmc, child);
if (err < 0)
break;
@@ -3593,6 +3593,32 @@ static const char * const tegra210_powergates[] = {
[TEGRA_POWERGATE_VE2] = "ve2",
};
static const char * const tegra210b01_powergates[] = {
[TEGRA_POWERGATE_CPU] = "crail",
[TEGRA_POWERGATE_3D] = "3d",
[TEGRA_POWERGATE_PCIE] = "pcie",
[TEGRA_POWERGATE_MPE] = "mpe",
[TEGRA_POWERGATE_SATA] = "sata",
[TEGRA_POWERGATE_CPU1] = "cpu1",
[TEGRA_POWERGATE_CPU2] = "cpu2",
[TEGRA_POWERGATE_CPU3] = "cpu3",
[TEGRA_POWERGATE_CPU0] = "cpu0",
[TEGRA_POWERGATE_C0NC] = "c0nc",
[TEGRA_POWERGATE_SOR] = "sor",
[TEGRA_POWERGATE_DIS] = "dis",
[TEGRA_POWERGATE_DISB] = "disb",
[TEGRA_POWERGATE_XUSBA] = "xusba",
[TEGRA_POWERGATE_XUSBB] = "xusbb",
[TEGRA_POWERGATE_XUSBC] = "xusbc",
[TEGRA_POWERGATE_VIC] = "vic",
[TEGRA_POWERGATE_IRAM] = "iram",
[TEGRA_POWERGATE_NVDEC] = "nvdec",
[TEGRA_POWERGATE_NVJPG] = "nvjpg",
[TEGRA_POWERGATE_AUD] = "aud",
[TEGRA_POWERGATE_DFD] = "dfd",
};
static const u8 tegra210_cpu_powergates[] = {
TEGRA_POWERGATE_CPU0,
TEGRA_POWERGATE_CPU1,
@@ -3814,13 +3840,13 @@ static const struct pinctrl_pin_desc tegra210b01_pin_descs[] = {
static const struct tegra_pmc_soc tegra210b01_pmc_soc = {
.supports_core_domain = false,
.num_powergates = ARRAY_SIZE(tegra210_powergates),
.powergates = tegra210_powergates,
.num_powergates = ARRAY_SIZE(tegra210b01_powergates),
.powergates = tegra210b01_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra210_cpu_powergates),
.cpu_powergates = tegra210_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = true,
.needs_mbist_war = true,
.needs_mbist_war = false,
.has_impl_33v_pwr = false,
.maybe_tz_only = true,
.num_io_pads = ARRAY_SIZE(tegra210b01_io_pads),

View File

@@ -110,6 +110,15 @@ config TYPEC_WUSB3801
If you choose to build this driver as a dynamically linked module, the
module will be called wusb3801.ko.
config TYPEC_BM92TXX
tristate "Rohm Semiconductor BM92TXX USB Type-C Support"
depends on I2C
depends on USB_ROLE_SWITCH
help
Say yes here to support for Rohm Semiconductor BM92TXX. This is a USB
Type-C connection IC. This driver provies common support for power
negotiation, USB ID detection and Hot-plug-detection on Display Port.
source "drivers/usb/typec/mux/Kconfig"
source "drivers/usb/typec/altmodes/Kconfig"

View File

@@ -11,4 +11,5 @@ obj-$(CONFIG_TYPEC_HD3SS3220) += hd3ss3220.o
obj-$(CONFIG_TYPEC_STUSB160X) += stusb160x.o
obj-$(CONFIG_TYPEC_RT1719) += rt1719.o
obj-$(CONFIG_TYPEC_WUSB3801) += wusb3801.o
obj-$(CONFIG_TYPEC_BM92TXX) += bm92txx.o
obj-$(CONFIG_TYPEC) += mux/

2631
drivers/usb/typec/bm92txx.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -125397,23 +125397,29 @@ member {
offset: 2880
}
member {
id: 0x8998723d
name: "gpu_process_id"
id: 0x716f03bc
name: "gpu_iddq_value"
type_id: 0x6720d32f
offset: 256
offset: 384
}
member {
id: 0xc59015c8
name: "gpu_speedo_id"
id: 0x8998764f
name: "gpu_process_id"
type_id: 0x6720d32f
offset: 288
}
member {
id: 0x1839ab9c
name: "gpu_speedo_value"
id: 0xc59016d6
name: "gpu_speedo_id"
type_id: 0x6720d32f
offset: 320
}
member {
id: 0x1839a802
name: "gpu_speedo_value"
type_id: 0x6720d32f
offset: 352
}
member {
id: 0x220ee7b2
name: "gpuva"
@@ -189897,10 +189903,10 @@ member {
bitsize: 1
}
member {
id: 0x2bdf1e4c
id: 0x2bdf18a9
name: "platform"
type_id: 0x4bb568ad
offset: 384
offset: 448
}
member {
id: 0x38c654ae
@@ -210651,10 +210657,10 @@ member {
offset: 12480
}
member {
id: 0x94eb2e6e
id: 0x94eb2857
name: "revision"
type_id: 0x43f6ac22
offset: 352
offset: 416
}
member {
id: 0xbcd2bfaa
@@ -227338,6 +227344,12 @@ member {
type_id: 0x3e10b518
offset: 256
}
member {
id: 0x97cc708c
name: "soc_iddq_value"
type_id: 0x6720d32f
offset: 256
}
member {
id: 0x8d753502
name: "soc_process_id"
@@ -228117,6 +228129,12 @@ member {
type_id: 0xc9082b19
offset: 704
}
member {
id: 0x9b8091d9
name: "speedo_rev"
type_id: 0x6720d32f
offset: 512
}
member {
id: 0xd0391586
name: "spi"
@@ -248697,6 +248715,12 @@ member {
type_id: 0x790929c4
offset: 8512
}
member {
id: 0xe7a15159
name: "ucm"
type_id: 0x7c124706
offset: 480
}
member {
id: 0x14b7816e
name: "ucontext"
@@ -340766,7 +340790,7 @@ struct_union {
kind: STRUCT
name: "tegra_sku_info"
definition {
bytesize: 52
bytesize: 68
member_id: 0x159f315d
member_id: 0x7be41b46
member_id: 0x9bd81e85
@@ -340775,11 +340799,15 @@ struct_union {
member_id: 0x8d753502
member_id: 0x509bfc34
member_id: 0x0ef921fa
member_id: 0x8998723d
member_id: 0xc59015c8
member_id: 0x1839ab9c
member_id: 0x94eb2e6e
member_id: 0x2bdf1e4c
member_id: 0x97cc708c
member_id: 0x8998764f
member_id: 0xc59016d6
member_id: 0x1839a802
member_id: 0x716f03bc
member_id: 0x94eb2857
member_id: 0x2bdf18a9
member_id: 0xe7a15159
member_id: 0x9b8091d9
}
}
struct_union {
@@ -370359,9 +370387,27 @@ enumeration {
value: 5
}
enumerator {
name: "TEGRA_REVISION_MAX"
name: "TEGRA_REVISION_B01"
value: 6
}
enumerator {
name: "TEGRA_REVISION_MAX"
value: 7
}
}
}
enumeration {
id: 0x7c124706
name: "tegra_ucm"
definition {
underlying_type_id: 0x4585663f
enumerator {
name: "TEGRA_UCM1"
}
enumerator {
name: "TEGRA_UCM2"
value: 1
}
}
}
enumeration {
@@ -505039,7 +505085,7 @@ elf_symbol {
name: "tegra_sku_info"
is_defined: true
symbol_type: OBJECT
crc: 0xbbcfcffc
crc: 0xe4a4fdfb
type_id: 0x539be05c
full_name: "tegra_sku_info"
}

View File

@@ -720,11 +720,14 @@
memstart_addr
mipi_dsi_attach
mipi_dsi_create_packet
mipi_dsi_dcs_read
mipi_dsi_dcs_set_pixel_format
mipi_dsi_detach
mipi_dsi_driver_register_full
mipi_dsi_driver_unregister
mipi_dsi_host_register
mipi_dsi_host_unregister
mipi_dsi_set_maximum_return_packet_size
misc_deregister
misc_register
__mmap_lock_do_trace_acquire_returned
@@ -1184,6 +1187,7 @@
up_read
up_write
usb_control_msg
usb_role_switch_get_role
usb_role_switch_put
usb_role_switch_set_role
__usecs_to_jiffies
@@ -1244,6 +1248,14 @@
report_iommu_fault
tegra_mc_probe_device
# required by bm92txx.ko
devm_gpio_request
extcon_get_state
extcon_set_state
fwnode_graph_get_endpoint_by_id
fwnode_graph_get_remote_endpoint
regulator_set_current_limit
# required by bq24190_charger.ko
kstrtou8
power_supply_get_property_from_supplier
@@ -2019,11 +2031,15 @@
devm_of_find_backlight
mipi_dsi_dcs_enter_sleep_mode
mipi_dsi_dcs_exit_sleep_mode
mipi_dsi_dcs_read
mipi_dsi_dcs_set_display_off
mipi_dsi_dcs_set_display_on
mipi_dsi_dcs_set_pixel_format
mipi_dsi_set_maximum_return_packet_size
# required by panel-nx-dsi.ko
mipi_dsi_dcs_set_column_address
mipi_dsi_dcs_set_page_address
mipi_dsi_dcs_set_tear_on
mipi_dsi_dcs_write
of_find_backlight_by_node
# required by panel-simple.ko
drm_bus_flags_from_videomode
@@ -2122,7 +2138,6 @@
usb_phy_set_event
usb_remove_phy
usb_role_switch_get_drvdata
usb_role_switch_get_role
usb_role_switch_register
usb_role_switch_set_drvdata
usb_role_switch_unregister

View File

@@ -409,9 +409,105 @@
#define TEGRA210_CLK_DMIC3_SYNC_CLK 392
#define TEGRA210_CLK_DMIC3_SYNC_CLK_MUX 393
#define TEGRA210_CLK_C2BUS 401
#define TEGRA210_CLK_C3BUS 402
#define TEGRA210_CLK_VIC03_CBUS 403
#define TEGRA210_CLK_NVJPG_CBUS 404
#define TEGRA210_CLK_SE_CBUS 405
#define TEGRA210_CLK_TSECB_CBUS 406
#define TEGRA210_CLK_CAP_C2BUS 407
#define TEGRA210_CLK_CAP_VCORE_C2BUS 408
#define TEGRA210_CLK_CAP_THROTTLE_C2BUS 409
#define TEGRA210_CLK_FLOOR_C2BUS 410
#define TEGRA210_CLK_OVERRIDE_C2BUS 411
#define TEGRA210_CLK_EDP_C2BUS 412
#define TEGRA210_CLK_NVENC_CBUS 413
#define TEGRA210_CLK_NVDEC_CBUS 414
#define TEGRA210_CLK_VIC_FLOOR_CBUS 415
#define TEGRA210_CLK_CAP_C3BUS 416
#define TEGRA210_CLK_CAP_VCORE_C3BUS 417
#define TEGRA210_CLK_CAP_THROTTLE_C3BUS 418
#define TEGRA210_CLK_FLOOR_C3BUS 419
#define TEGRA210_CLK_OVERRIDE_C3BUS 420
#define TEGRA210_CLK_VI_CBUS 421
#define TEGRA210_CLK_ISP_CBUS 422
#define TEGRA210_CLK_OVERRIDE_CBUS 423
#define TEGRA210_CLK_CAP_VCORE_CBUS 424
#define TEGRA210_CLK_VIA_VI_CBUS 425
#define TEGRA210_CLK_VIB_VI_CBUS 426
#define TEGRA210_CLK_ISPA_ISP_CBUS 427
#define TEGRA210_CLK_ISPB_ISP_CBUS 428
#define TEGRA210_CLK_SBUS 429
#define TEGRA210_CLK_AVP_SCLK 430
#define TEGRA210_CLK_BSEA_SCLK 431
#define TEGRA210_CLK_USBD_SCLK 432
#define TEGRA210_CLK_USB1_SCLK 433
#define TEGRA210_CLK_USB2_SCLK 434
#define TEGRA210_CLK_USB3_SCLK 435
#define TEGRA210_CLK_WAKE_SCLK 436
#define TEGRA210_CLK_CAMERA_SCLK 437
#define TEGRA210_CLK_MON_AVP 438
#define TEGRA210_CLK_CAP_SCLK 439
#define TEGRA210_CLK_CAP_VCORE_SCLK 440
#define TEGRA210_CLK_CAP_THROTTLE_SCLK 441
#define TEGRA210_CLK_FLOOR_SCLK 442
#define TEGRA210_CLK_OVERRIDE_SCLK 443
#define TEGRA210_CLK_SBC1_SCLK 444
#define TEGRA210_CLK_SBC2_SCLK 445
#define TEGRA210_CLK_SBC3_SCLK 446
#define TEGRA210_CLK_SBC4_SCLK 447
#define TEGRA210_CLK_QSPI_SCLK 448
#define TEGRA210_CLK_BOOT_APB_SCLK 449
#define TEGRA210_CLK_EMC_MASTER 450
#define TEGRA210_CLK_GBUS 487
#define TEGRA210_CLK_GM20B_GBUS 488
#define TEGRA210_CLK_CAP_GBUS 489
#define TEGRA210_CLK_EDP_GBUS 490
#define TEGRA210_CLK_CAP_VGPU_GBUS 491
#define TEGRA210_CLK_CAP_THROTTLE_GBUS 492
#define TEGRA210_CLK_CAP_PROFILE_GBUS 493
#define TEGRA210_CLK_OVERRIDE_GBUS 494
#define TEGRA210_CLK_FLOOR_GBUS 495
#define TEGRA210_CLK_FLOOR_PROFILE_GBUS 496
#define TEGRA210_CLK_HOST1X_MASTER 497
#define TEGRA210_CLK_NV_HOST1X 498
#define TEGRA210_CLK_VI_HOST1X 499
#define TEGRA210_CLK_VII2C_HOST1X 500
#define TEGRA210_CLK_CAP_HOST1X 501
#define TEGRA210_CLK_CAP_VCORE_HOST1X 502
#define TEGRA210_CLK_FLOOR_HOST1X 503
#define TEGRA210_CLK_OVERRIDE_HOST1X 504
#define TEGRA210_CLK_MSELECT_MASTER 505
#define TEGRA210_CLK_CPU_MSELECT 506
#define TEGRA210_CLK_PCIE_MSELECT 507
#define TEGRA210_CLK_CAP_VCORE_MSELECT 508
#define TEGRA210_CLK_OVERRIDE_MSELECT 509
#define TEGRA210_CLK_APE_MASTER 510
#define TEGRA210_CLK_ADMA_APE 511
#define TEGRA210_CLK_ADSP_APE 512
#define TEGRA210_CLK_XBAR_APE 513
#define TEGRA210_CLK_CAP_VCORE_APE 514
#define TEGRA210_CLK_OVERRIDE_APE 515
#define TEGRA210_CLK_ABUS 516
#define TEGRA210_CLK_ADSP_CPU_ABUS 517
#define TEGRA210_CLK_CAP_VCORE_ABUS 518
#define TEGRA210_CLK_OVERRIDE_ABUS 519
#define TEGRA210_CLK_VCM_SCLK 520
#define TEGRA210_CLK_VCM_AHB_SCLK 521
#define TEGRA210_CLK_VCM_APB_SCLK 522
#define TEGRA210_CLK_AHB_SCLK 523
#define TEGRA210_CLK_APB_SCLK 524
#define TEGRA210_CLK_SDMMC4_AHB_SCLK 525
/* 526 */
#define TEGRA210_CLK_CBUS 527
#define TEGRA210_CLK_VI_V4L2_CBUS 528
#define TEGRA210_CLK_VI_BYPASS_CBUS 529
#define TEGRA210_CLK_BWMGR_EMC 530
#define TEGRA210_CLK_UTMIPLL_60M 531
#define TEGRA210_CLK_PLL_P_UPHY_OUT 532
#define TEGRA210_CLK_WIFI_SCLK 533
#define TEGRA210_CLK_CLK_MAX 533
#define TEGRA210_CLK_CLK_MAX 534
#endif /* _DT_BINDINGS_CLOCK_TEGRA210_CAR_H */

View File

@@ -0,0 +1,16 @@
/*
* This header defines the trip temperatures for Tegra210
*/
#ifndef _DT_BINDINGS_THERMAL_TEGRA210_DFLL_TRIPS_H
#define _DT_BINDINGS_THERMAL_TEGRA210_DFLL_TRIPS_H
#define TEGRA210_DFLL_THERMAL_FLOOR_0 15000
#define TEGRA210_DFLL_THERMAL_FLOOR_1 30000
#define TEGRA210_DFLL_THERMAL_FLOOR_2 50000
#define TEGRA210_DFLL_THERMAL_FLOOR_3 70000
#define TEGRA210_DFLL_THERMAL_FLOOR_4 120000
#define TEGRA210_DFLL_THERMAL_CAP_0 66000
#define TEGRA210_DFLL_THERMAL_CAP_1 86000
#endif /* _DT_BINDINGS_THERMAL_TEGRA210_DFLL_TRIPS_H */

View File

@@ -0,0 +1,28 @@
/*
* This header defines the trip temperatures for Tegra210b01
*/
#ifndef _DT_BINDINGS_THERMAL_TEGRA210B01_TRIPS_H
#define _DT_BINDINGS_THERMAL_TEGRA210B01_TRIPS_H
/* DFLL trips, in millicelsius */
#define TEGRA210B01_DFLL_THERMAL_FLOOR_0 20000
#define TEGRA210B01_DFLL_THERMAL_FLOOR_1 70000
#define TEGRA210B01_DFLL_THERMAL_CAP_0 64000
#define TEGRA210B01_DFLL_THERMAL_CAP_1 84000
/* GPU DVFS thermal trips, in millicelsius */
#define TEGRA210B01_GPU_DVFS_THERMAL_MIN -25000
#define TEGRA210B01_GPU_DVFS_THERMAL_TRIP_1 20000
#define TEGRA210B01_GPU_DVFS_THERMAL_TRIP_2 30000
#define TEGRA210B01_GPU_DVFS_THERMAL_TRIP_3 50000
#define TEGRA210B01_GPU_DVFS_THERMAL_TRIP_4 70000
#define TEGRA210B01_GPU_DVFS_THERMAL_TRIP_5 90000
#define TEGRA210B01_GPU_DVFS_THERMAL_CAP_1 83000
/* SoC DVFS thermal trips, in millicelsius */
#define TEGRA210B01_SOC_THERMAL_FLOOR_0 20000
#define TEGRA210B01_SOC_THERMAL_CAP_0 84000
#endif /* _DT_BINDINGS_THERMAL_TEGRA210B01_TRIPS_H */

View File

@@ -35,10 +35,33 @@ struct of_phandle_args;
* POST_RATE_CHANGE - called after the clk rate change has successfully
* completed. Callbacks must always return NOTIFY_DONE or NOTIFY_OK.
*
* PRE_SUBTREE_UPDATE - called before rate change is propagated down to
* sub-tree rooted in clk. Callbacks must always return NOTIFY_DONE
* or NOTIFY_OK.
*
* POST_SUBTREE_UPDATE - called after rate change is propagated down to
* sub-tree rooted in clk. Callbacks must always return NOTIFY_DONE
* or NOTIFY_OK.
*
* PRE_PARENT_CHANGE - called immediately before the clk parent is changed,
* to indicate that the parent change will proceed. Callbacks may either
* return NOTIFY_DONE, NOTIFY_OK, NOTIFY_STOP or NOTIFY_BAD.
*
* ABORT_PARENT_CHANGE: called if the parent change failed for some reason
* after PRE_PARENT_CHANGE. Callbacks must always return NOTIFY_DONE or
* NOTIFY_OK.
*
* POST_PARENT_CHANGE - called after the clk parent change has successfully
* completed. Callbacks must always return NOTIFY_DONE or NOTIFY_OK.
*/
#define PRE_RATE_CHANGE BIT(0)
#define POST_RATE_CHANGE BIT(1)
#define ABORT_RATE_CHANGE BIT(2)
#define PRE_SUBTREE_CHANGE BIT(3)
#define POST_SUBTREE_CHANGE BIT(4)
#define PRE_PARENT_CHANGE BIT(5)
#define POST_PARENT_CHANGE BIT(6)
#define ABORT_PARENT_CHANGE BIT(7)
/**
* struct clk_notifier - associate a clk with a notifier

View File

@@ -231,6 +231,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
int regulator_set_voltage_time(struct regulator *regulator,
int old_uV, int new_uV);
int regulator_get_voltage(struct regulator *regulator);
int regulator_get_constraint_voltages(struct regulator *regulator,
int *min_uV, int *max_uV);
int regulator_sync_voltage(struct regulator *regulator);
int regulator_set_current_limit(struct regulator *regulator,
int min_uA, int max_uA);

View File

@@ -33,6 +33,7 @@ enum tegra_revision {
TEGRA_REVISION_A03,
TEGRA_REVISION_A03p,
TEGRA_REVISION_A04,
TEGRA_REVISION_B01,
TEGRA_REVISION_MAX,
};
@@ -50,6 +51,11 @@ enum tegra_platform {
TEGRA_PLATFORM_MAX,
};
enum tegra_ucm {
TEGRA_UCM1 = 0,
TEGRA_UCM2,
};
struct tegra_sku_info {
int sku_id;
int cpu_process_id;
@@ -59,11 +65,17 @@ struct tegra_sku_info {
int soc_process_id;
int soc_speedo_id;
int soc_speedo_value;
int soc_iddq_value;
int gpu_process_id;
int gpu_speedo_id;
int gpu_speedo_value;
int gpu_iddq_value;
enum tegra_revision revision;
enum tegra_platform platform;
enum tegra_ucm ucm;
int speedo_rev;
};
#ifdef CONFIG_ARCH_TEGRA
@@ -71,6 +83,9 @@ extern struct tegra_sku_info tegra_sku_info;
u32 tegra_read_straps(void);
u32 tegra_read_ram_code(void);
int tegra_fuse_readl(unsigned long offset, u32 *value);
int tegra_fuse_get_cpu_iddq(void);
int tegra_fuse_get_gpu_iddq(void);
int tegra_fuse_get_soc_iddq(void);
u32 tegra_read_chipid(void);
u8 tegra_get_chip_id(void);
u8 tegra_get_platform(void);
@@ -94,6 +109,21 @@ static inline int tegra_fuse_readl(unsigned long offset, u32 *value)
return -ENODEV;
}
static inline int tegra_fuse_get_cpu_iddq(void)
{
return -ENODEV;
}
static inline int tegra_fuse_get_gpu_iddq(void)
{
return -ENODEV;
}
static inline int tegra_fuse_get_soc_iddq(void)
{
return -ENODEV;
}
static inline u32 tegra_read_chipid(void)
{
return 0;

View File

@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved
*/
#ifndef _TEGRA_DFLL_H_
#define _TEGRA_DFLL_H_
#include <linux/kernel.h>
#include <linux/platform_device.h>
enum tegra_dfll_thermal_type {
TEGRA_DFLL_THERMAL_FLOOR = 0,
TEGRA_DFLL_THERMAL_CAP,
};
struct tegra_dfll;
extern struct tegra_dfll *tegra_dfll_get_by_phandle(struct device_node *np,
const char *prop);
extern int tegra_dfll_update_thermal_index(struct tegra_dfll *td,
enum tegra_dfll_thermal_type type,
unsigned long new_index);
extern int tegra_dfll_get_thermal_index(struct tegra_dfll *td,
enum tegra_dfll_thermal_type type);
extern int tegra_dfll_count_thermal_states(struct tegra_dfll *td,
enum tegra_dfll_thermal_type type);
int tegra_dfll_set_external_floor_mv(int external_floor_mv);
u32 tegra_dfll_get_thermal_floor_mv(void);
u32 tegra_dfll_get_peak_thermal_floor_mv(void);
u32 tegra_dfll_get_thermal_cap_mv(void);
u32 tegra_dfll_get_min_millivolts(void);
struct rail_alignment *tegra_dfll_get_alignment(void);
const char *tegra_dfll_get_cvb_version(void);
#endif