linux-stable/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi

1544 lines
30 KiB
Plaintext
Raw Normal View History

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Google Trogdor device tree source (common between revisions)
*
* Copyright 2019 Google LLC.
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/gpio-keys.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include <dt-bindings/sound/sc7180-lpass.h>
#include "sc7180.dtsi"
#include "sc7180-firmware-tfa.dtsi"
/* PMICs depend on spmi_bus label and so must come after sc7180.dtsi */
#include "pm6150.dtsi"
#include "pm6150l.dtsi"
/ {
thermal-zones {
charger_thermal: charger-thermal {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&pm6150_adc_tm 0>;
trips {
charger-crit {
temperature = <125000>;
hysteresis = <1000>;
type = "critical";
};
};
};
};
};
/*
* Reserved memory changes
*
* Delete all unused memory nodes and define the peripheral memory regions
* required by the board dts.
*/
/delete-node/ &hyp_mem;
/delete-node/ &ipa_fw_mem;
/delete-node/ &xbl_mem;
/delete-node/ &aop_mem;
/delete-node/ &sec_apps_mem;
/delete-node/ &tz_mem;
/* Increase the size from 2MB to 8MB */
&rmtfs_mem {
reg = <0x0 0x94600000 0x0 0x800000>;
};
/ {
reserved-memory {
atf_mem: memory@80b00000 {
reg = <0x0 0x80b00000 0x0 0x100000>;
no-map;
};
mpss_mem: memory@86000000 {
reg = <0x0 0x86000000 0x0 0x2000000>;
no-map;
};
venus_mem: memory@8f600000 {
reg = <0 0x8f600000 0 0x500000>;
no-map;
};
wlan_mem: memory@94100000 {
reg = <0x0 0x94100000 0x0 0x200000>;
no-map;
};
mba_mem: memory@94400000 {
reg = <0x0 0x94400000 0x0 0x200000>;
no-map;
};
mdata_mem: mpss-metadata {
alloc-ranges = <0x0 0xa0000000 0x0 0x20000000>;
size = <0x0 0x4000>;
no-map;
};
};
aliases {
bluetooth0 = &bluetooth;
hsuart0 = &uart3;
serial0 = &uart8;
wifi0 = &wifi;
};
chosen {
stdout-path = "serial0:115200n8";
};
/* FIXED REGULATORS - parents above children */
/* This is the top level supply and variable voltage */
ppvar_sys: ppvar-sys-regulator {
compatible = "regulator-fixed";
regulator-name = "ppvar_sys";
regulator-always-on;
regulator-boot-on;
};
/* This divides ppvar_sys by 2, so voltage is variable */
src_vph_pwr: src-vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "src_vph_pwr";
/* EC turns on with switchcap_on; always on for AP */
regulator-always-on;
regulator-boot-on;
vin-supply = <&ppvar_sys>;
};
pp5000_a: pp5000-a-regulator {
compatible = "regulator-fixed";
regulator-name = "pp5000_a";
/* EC turns on with en_pp5000_a; always on for AP */
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&ppvar_sys>;
};
pp3300_a: pp3300-a-regulator {
compatible = "regulator-fixed";
regulator-name = "pp3300_a";
/* EC turns on with en_pp3300_a; always on for AP */
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
/*
* Actually should be pp3300 but that's practically an alias for
* pp3300_a so we use pp3300's vin-supply here to avoid one more
* node.
*/
vin-supply = <&ppvar_sys>;
};
pp1800_ec:
pp1800_sensors:
pp1800_ldo: pp1800-ldo-regulator {
compatible = "regulator-fixed";
regulator-name = "pp1800_ldo";
/* EC turns on with hibernate_l; always on for AP */
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
/*
* Actually should be pp1800_h1 but we don't have any need to
* model that so we use the parent of pp1800_h1.
*/
vin-supply = <&pp3300_a>;
};
pp1800_uf_cam: pp1800-uf-cam-regulator {
compatible = "regulator-fixed";
regulator-name = "pp1800_uf_cam";
status = "disabled";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
gpio = <&tlmm 6 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
pinctrl-0 = <&uf_cam_en>;
vin-supply = <&pp1800_ldo>;
regulator-enable-ramp-delay = <1000>;
};
pp1800_wf_cam: pp1800-wf-cam-regulator {
compatible = "regulator-fixed";
regulator-name = "pp1800_wf_cam";
status = "disabled";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
pinctrl-0 = <&wf_cam_en>;
vin-supply = <&pp1800_ldo>;
regulator-enable-ramp-delay = <1000>;
};
pp2800_uf_cam: pp2800-uf-cam-regulator {
compatible = "regulator-fixed";
regulator-name = "pp2800_uf_cam";
status = "disabled";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
gpio = <&tlmm 6 GPIO_ACTIVE_HIGH>;
enable-active-high;
/*
* The pinconf can only be referenced once so we put it on the
* first regulator and comment it out here.
* pinctrl-names = "default";
* pinctrl-0 = <&uf_cam_en>;
*/
vin-supply = <&pp3300_a>;
};
pp2800_vcm_wf_cam:
pp2800_wf_cam: pp2800-wf-cam-regulator {
compatible = "regulator-fixed";
regulator-name = "pp2800_wf_cam";
status = "disabled";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
enable-active-high;
/*
* The pinconf can only be referenced once so we put it on the
* first regulator and comment it out here.
* pinctrl-names = "default";
* pinctrl-0 = <&wf_cam_en>;
*/
vin-supply = <&pp3300_a>;
};
pp3300_audio:
pp3300_codec: pp3300-codec-regulator {
compatible = "regulator-fixed";
regulator-name = "pp3300_codec";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&tlmm 83 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
pinctrl-0 = <&en_pp3300_codec>;
vin-supply = <&pp3300_a>;
};
pp3300_dx_edp:
pp3300_ts: pp3300-dx-edp-regulator {
compatible = "regulator-fixed";
regulator-name = "pp3300_dx_edp";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&tlmm 30 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
pinctrl-0 = <&en_pp3300_dx_edp>;
vin-supply = <&pp3300_a>;
};
pp3300_fp_tp: pp3300-fp-tp-regulator {
compatible = "regulator-fixed";
regulator-name = "pp3300_fp_tp";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
/* AP turns on with PP1800_VIO_OUT; always on for AP */
regulator-always-on;
regulator-boot-on;
vin-supply = <&pp3300_a>;
};
pp3300_hub: pp3300-hub-regulator {
compatible = "regulator-fixed";
regulator-name = "pp3300_hub";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&tlmm 84 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
pinctrl-0 = <&en_pp3300_hub>;
/* The BIOS leaves this regulator on */
regulator-boot-on;
vin-supply = <&pp3300_a>;
};
/* BOARD-SPECIFIC TOP LEVEL NODES */
backlight: backlight {
compatible = "pwm-backlight";
/* The panels don't seem to like anything below ~ 5% */
brightness-levels = <
196 256 324 400 484 576 676 784 900 1024 1156 1296
1444 1600 1764 1936 2116 2304 2500 2704 2916 3136
3364 3600 3844 4096
>;
num-interpolated-steps = <64>;
default-brightness-level = <951>;
pwms = <&cros_ec_pwm 1>;
enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
power-supply = <&ppvar_sys>;
pinctrl-names = "default";
pinctrl-0 = <&ap_edp_bklten>;
};
gpio_keys: gpio-keys {
compatible = "gpio-keys";
status = "disabled";
pinctrl-names = "default";
pinctrl-0 = <&pen_pdct_l>;
pen_insert: switch-pen-insert {
label = "Pen Insert";
/* Insert = low, eject = high */
gpios = <&tlmm 52 GPIO_ACTIVE_LOW>;
linux,code = <SW_PEN_INSERTED>;
linux,input-type = <EV_SW>;
wakeup-event-action = <EV_ACT_DEASSERTED>;
wakeup-source;
};
};
max98360a: audio-codec-0 {
compatible = "maxim,max98360a";
pinctrl-names = "default";
pinctrl-0 = <&amp_en>;
sdmode-gpios = <&tlmm 23 GPIO_ACTIVE_HIGH>;
#sound-dai-cells = <0>;
};
pwmleds {
compatible = "pwm-leds";
keyboard_backlight: led-0 {
status = "disabled";
label = "cros_ec::kbd_backlight";
function = LED_FUNCTION_KBD_BACKLIGHT;
pwms = <&cros_ec_pwm 0>;
max-brightness = <1023>;
};
};
sound: sound {
compatible = "google,sc7180-trogdor";
audio-routing =
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
#address-cells = <1>;
#size-cells = <0>;
dai-link@0 {
link-name = "MultiMedia0";
reg = <MI2S_PRIMARY>;
cpu {
sound-dai = <&lpass_cpu MI2S_PRIMARY>;
};
sound_multimedia0_codec: codec {
sound-dai = <&alc5682 0 /* aif1 */>;
};
};
dai-link@1 {
link-name = "MultiMedia1";
reg = <MI2S_SECONDARY>;
cpu {
sound-dai = <&lpass_cpu MI2S_SECONDARY>;
};
sound_multimedia1_codec: codec {
sound-dai = <&max98360a>;
};
};
dai-link@5 {
link-name = "MultiMedia2";
reg = <LPASS_DP_RX>;
cpu {
sound-dai = <&lpass_cpu LPASS_DP_RX>;
};
codec {
sound-dai = <&mdss_dp>;
};
};
};
};
&qfprom {
vcc-supply = <&pp1800_l11a>;
};
&qspi {
status = "okay";
arm64: dts: qcom: sc7180: Fix trogdor qspi pin config In commit 7ec3e67307f8 ("arm64: dts: qcom: sc7180-trogdor: add initial trogdor and lazor dt") we specified the pull settings on the boot SPI (the qspi) data lines as pullups to "park" the lines. This seemed like the right thing to do, but I never really probed the lines to confirm. Since that time, I've done A LOT of research, experiements and poking of the lines with a voltmeter. A first batch of discoveries: - There is an external pullup on CS (clearly shown on schematics) - There are weak external pulldowns on CLK/MOSI (believed to be Cr50's internal pulldowns) - There is no pull on MISO. - When qspi isn't actively transferring it still drives CS, CLK, and MOSI. CS and MOSI are driven high and CLK is driven low. It does not drive MISO and (if no internal pulls are enabled) the line floats. The above means that it's good to have some sort of pull on MISO, at the very least. The pullup that we had before was actually fine (and my voltmeter confirms that it actually affected the state of the pin) but a pulldown would work equally well (and would match MOSI and CLK better). The above also means that we could save a tiny bit of power (not measurable by my setup) by setting up a sleep state for these pins. If nothing else this prevents us from driving high against Cr50's internal pulldown on MOSI. However, Qualcomm has also asserted in the past that it burns a little extra power to drive a pin, especially since these are configured with a slightly higher drive strength Let's fix all this. Since the external pulls are different for the two data lines, we'll split them into separate configs. Then we'll change the MISO pin to a pulldown and add a sleep state. On a slightly tangental (but not totally unrelated note), I also discovered some interesting things with these pins in suspend. First, I found that if we don't switch the pins to GPIO that the qspi peripheral continues to drive them in suspend. That'll be solved by what we're already doing above. Second, I found that something in the system suspend path (after Linux stops running) reconfigures these pins so that they don't have their normal pulls enabled but instead change to "keepers" (bias-bus-hold in DT speak). If a pin was floating before we entered suspend then it would stop floating. I found that I could manually pull a pin to a different level and then probe it and it would stay there. This is exactly keeper behavior. With the solution we have the switch to "keeper" doesn't matter too much but it's good to document. While talking about "keepers", it can also be noted that I found that the "keepers" on these pins were at least enough to win a fight against Cr50's internal pulls. That means it's best to make sure that the state of the pins are already correct before the mysterious transition to a keeper. Otherwise we'll burn (a small amount of) power in S3 via this fight. Luckily with the current solution we don't hit this case. NOTE: I've left "sc7180-idp" behavior totally alone in this patch. I didn't add a sleep state and I didn't change any pulls--I just adapted it to the fact that the data lines have separate configs. Qualcomm doesn't provide me with schematics for IDP and thus I don't actually know how the pulls are configured. Since this is just a development platform and worked well enough, it seems safer to leave it alone. Dependencies: - This patch has a hard dependency on ("pinctrl: qcom: Support OUTPUT_ENABLE; deprecate INPUT_ENABLE"). Something in the boot code seemed to have been confused and thought it needed to set the "OUTPUT ENABLE" bit for these pins even though it was using them as SPI. Thus if we don't honor the "output-disable" property we could end up driving the SPI pins while in sleep mode. - In general, it's probably best not to backport this to a kernel that doesn't have commit d21f4b7ffc22 ("pinctrl: qcom: Avoid glitching lines when we first mux to output"). That landed a while ago, but it's still good to be explicit in case someone was backporting. If we don't have that then there might be a glitch when we first switch over to GPIO before we disable the output. - This patch _doesn't_ really have any dependency on the qspi driver patch that supports setting the pinctrl sleep state--they can go in either order. If we define the sleep state and the driver never selects it that's fine. If the driver tries to select a sleep state that we don't define that's fine. Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Bjorn Andersson <andersson@kernel.org> Link: https://lore.kernel.org/r/20230323102605.12.I6f03f86546e6ce9abb1d24fd9ece663c3a5b950c@changeid
2023-03-23 17:30:16 +00:00
pinctrl-names = "default", "sleep";
pinctrl-0 = <&qspi_clk>, <&qspi_cs0>, <&qspi_data0>, <&qspi_data1>;
pinctrl-1 = <&qspi_sleep>;
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <37500000>;
spi-tx-bus-width = <2>;
spi-rx-bus-width = <2>;
};
};
&apps_rsc {
regulators-0 {
compatible = "qcom,pm6150-rpmh-regulators";
qcom,pmic-id = "a";
vddpx_1:
vdd2:
pp1125_s1a: smps1 {
regulator-min-microvolt = <1128000>;
regulator-max-microvolt = <1128000>;
};
vdd_qlink_lv:
vdd_qlink_lv_ck:
vdd_qusb_hs0_core:
vdd_ufs1_core:
vdda_mipi_csi0_0p9:
vdda_mipi_csi1_0p9:
vdda_mipi_csi2_0p9:
vdda_mipi_csi3_0p9:
vdda_mipi_dsi0_pll:
vdda_pll_cc_ebi01:
vdda_qrefs_0p9:
vdda_usb_ss_dp_core:
pp900_l4a: ldo4 {
regulator-min-microvolt = <824000>;
regulator-max-microvolt = <928000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdd_cx_wlan:
pp800_l9a: ldo9 {
regulator-min-microvolt = <488000>;
regulator-max-microvolt = <800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdd1:
vddpx_3:
vddpx_7:
vio_in:
pp1800_l10a: ldo10 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdd_qfprom:
vdda_apc1_cs_1p8:
vdda_qrefs_1p8:
vdda_qusb_hs0_1p8:
vddpx_11:
vreg_bb_clk:
pp1800_l11a: ldo11 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
mcp_vccq:
pp1800_l12a_r: ldo12 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
arm64: dts: qcom: Clean up sc7180-trogdor voltage rails For a bunch of rails we really don't do anything with them in Linux. These are things like modem voltage rails that the modem manages these itself and core rails (like IO rails) that are setup to just automagically do the right thing by the firmware. Let's stop even listing those rails in our device tree. The net result of this is that some of these rails might be able to go down to a lower voltage or perhaps transition to LPM (low power mode) sometimes. Here's a list of what we're doing and why: * L1A - only goes to SoC and doesn't seem associated with any particular peripheral. Kernel isn't doing anything with this. Removing from dts. NET IMPACT: rail might drop from 1.2V to 1.178V and switch to LPM in some cases depending on firmware. * L2A - only goes to SoC and doesn't seem associated with any particular peripheral. Kernel isn't doing anything with this. Removing from dts. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L3A - only goes to SoC and doesn't seem associated with any particular peripheral. Kernel isn't doing anything with this. Removing from dts. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L5A - seems to be totally unused as far as I can tell and doesn't even come off QSIP. Removing from dts. * L6A - only goes to SoC and doesn't seem associated with any particular peripheral (I think?). Kernel isn't doing anything with this. Removing from dts. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L16A - Looks like this is only used for internal RF stuff. Removing from dts. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L1C - Just goes to WiFi / Bluetooth. Trust how IDP has this set and put this back at 1.616V min. * L4C - This goes out to the eSIM among other places. This looks like it's intended to be for SIM card and modem manages. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L5C - This goes to the physical SIM. This looks like it's intended to be for SIM card and modem manages. NET IMPACT: rail might drop from 1.8V to 1.648V and switch to LPM in some cases depending on firmware. NOTE: in general for anything which is supposed to be managed by Linux I still left it all forced to HPM since I'm not 100% sure that all the needed calls to regulator_set_load() are in place and HPM is safer. Switching more things to LPM can happen in a future patch. ALSO NOTE: Power measurements showed no measurable difference after applying this patch, so perhaps it should be viewed more as a cleanup than any power savings. Reviewed-by: Alexandru M Stan <amstan@google.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://lore.kernel.org/r/20201207143255.1.Ib92ec35163682dec4b2fbb4bde0785cb6e6dde27@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
2020-12-07 22:33:02 +00:00
/*
* On trogdor this needs to match l10a since we use it to
* give power to things like SPI flash which communicate back
* on lines powered by l10a. Thus we force to 1.8V.
*/
pp1800_l13a: ldo13 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
regulator-always-on;
regulator-boot-on;
};
pp1800_prox:
pp1800_l14a: ldo14 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
pp1800_alc5682:
pp1800_l15a: ldo15 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdda_qusb_hs0_3p1:
vdd_pdphy:
pp3100_l17a: ldo17 {
regulator-min-microvolt = <2920000>;
regulator-max-microvolt = <3232000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
pp1800_pen:
pp1800_l18a: ldo18 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
mcp_vcc:
pp2850_l19a: ldo19 {
regulator-min-microvolt = <2960000>;
regulator-max-microvolt = <2960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
};
regulators-1 {
compatible = "qcom,pm6150l-rpmh-regulators";
qcom,pmic-id = "c";
pp1300_s8c: smps8 {
regulator-min-microvolt = <1120000>;
regulator-max-microvolt = <1408000>;
};
pp1800_l1c: ldo1 {
arm64: dts: qcom: Clean up sc7180-trogdor voltage rails For a bunch of rails we really don't do anything with them in Linux. These are things like modem voltage rails that the modem manages these itself and core rails (like IO rails) that are setup to just automagically do the right thing by the firmware. Let's stop even listing those rails in our device tree. The net result of this is that some of these rails might be able to go down to a lower voltage or perhaps transition to LPM (low power mode) sometimes. Here's a list of what we're doing and why: * L1A - only goes to SoC and doesn't seem associated with any particular peripheral. Kernel isn't doing anything with this. Removing from dts. NET IMPACT: rail might drop from 1.2V to 1.178V and switch to LPM in some cases depending on firmware. * L2A - only goes to SoC and doesn't seem associated with any particular peripheral. Kernel isn't doing anything with this. Removing from dts. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L3A - only goes to SoC and doesn't seem associated with any particular peripheral. Kernel isn't doing anything with this. Removing from dts. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L5A - seems to be totally unused as far as I can tell and doesn't even come off QSIP. Removing from dts. * L6A - only goes to SoC and doesn't seem associated with any particular peripheral (I think?). Kernel isn't doing anything with this. Removing from dts. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L16A - Looks like this is only used for internal RF stuff. Removing from dts. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L1C - Just goes to WiFi / Bluetooth. Trust how IDP has this set and put this back at 1.616V min. * L4C - This goes out to the eSIM among other places. This looks like it's intended to be for SIM card and modem manages. NET IMPACT: rail might switch to LPM in some cases depending on firmware. * L5C - This goes to the physical SIM. This looks like it's intended to be for SIM card and modem manages. NET IMPACT: rail might drop from 1.8V to 1.648V and switch to LPM in some cases depending on firmware. NOTE: in general for anything which is supposed to be managed by Linux I still left it all forced to HPM since I'm not 100% sure that all the needed calls to regulator_set_load() are in place and HPM is safer. Switching more things to LPM can happen in a future patch. ALSO NOTE: Power measurements showed no measurable difference after applying this patch, so perhaps it should be viewed more as a cleanup than any power savings. Reviewed-by: Alexandru M Stan <amstan@google.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://lore.kernel.org/r/20201207143255.1.Ib92ec35163682dec4b2fbb4bde0785cb6e6dde27@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
2020-12-07 22:33:02 +00:00
regulator-min-microvolt = <1616000>;
regulator-max-microvolt = <1984000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdd_wcss_adc_dac:
pp1300_l2c: ldo2 {
regulator-min-microvolt = <1168000>;
regulator-max-microvolt = <1304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
pp1200_brij:
vdd_ufs1_1p2:
vdda_csi0_1p25:
vdda_csi1_1p25:
vdda_csi2_1p25:
vdda_csi3_1p25:
vdda_hv_ebi0:
vdda_mipi_dsi0_1p2:
vdda_usb_ss_dp_1p2:
vddpx_10:
pp1200_l3c: ldo3 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vddpx_2:
ppvar_l6c: ldo6 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2952000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
pp3300_l7c: ldo7 {
regulator-min-microvolt = <3304000>;
regulator-max-microvolt = <3304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
pp1800_brij_vccio:
pp1800_edp_vpll:
pp1800_l8c: ldo8 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
pp2950_l9c: ldo9 {
regulator-min-microvolt = <2952000>;
regulator-max-microvolt = <2952000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
pp3300_l10c: ldo10 {
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3400000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
pp3300_l11c: ldo11 {
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3400000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
src_vreg_bob: bob {
regulator-min-microvolt = <3008000>;
regulator-max-microvolt = <3960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
};
};
};
ap_ec_spi: &spi6 {
status = "okay";
cros_ec: ec@0 {
compatible = "google,cros-ec-spi";
reg = <0>;
interrupt-parent = <&tlmm>;
interrupts = <94 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&ap_ec_int_l>;
spi-max-frequency = <3000000>;
wakeup-source;
cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
#pwm-cells = <1>;
};
i2c_tunnel: i2c-tunnel {
compatible = "google,cros-ec-i2c-tunnel";
google,remote-bus = <0>;
#address-cells = <1>;
#size-cells = <0>;
};
typec {
compatible = "google,cros-ec-typec";
#address-cells = <1>;
#size-cells = <0>;
usb_c0: connector@0 {
compatible = "usb-c-connector";
reg = <0>;
label = "left";
power-role = "dual";
data-role = "host";
try-power-role = "source";
};
usb_c1: connector@1 {
compatible = "usb-c-connector";
reg = <1>;
label = "right";
power-role = "dual";
data-role = "host";
try-power-role = "source";
};
};
};
};
ap_h1_spi: &spi0 {
status = "okay";
cr50: tpm@0 {
compatible = "google,cr50";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&h1_ap_int_odl>;
spi-max-frequency = <800000>;
interrupt-parent = <&tlmm>;
interrupts = <42 IRQ_TYPE_EDGE_RISING>;
};
};
&camcc {
status = "disabled";
};
ap_sar_sensor_i2c: &i2c5 {
clock-frequency = <400000>;
ap_sar_sensor: proximity@28 {
compatible = "semtech,sx9310";
reg = <0x28>;
#io-channel-cells = <1>;
pinctrl-names = "default";
pinctrl-0 = <&p_sensor_int_l>;
interrupt-parent = <&tlmm>;
interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&pp3300_a>;
svdd-supply = <&pp1800_prox>;
label = "proximity-wifi";
};
};
ap_tp_i2c: &i2c7 {
clock-frequency = <400000>;
trackpad: trackpad@15 {
compatible = "elan,ekth3000";
reg = <0x15>;
pinctrl-names = "default";
pinctrl-0 = <&tp_int_odl>;
interrupt-parent = <&tlmm>;
interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
vcc-supply = <&pp3300_fp_tp>;
wakeup-source;
};
};
hp_i2c: &i2c9 {
status = "okay";
clock-frequency = <400000>;
};
&lpasscc {
status = "okay";
};
&lpass_cpu {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&sec_mi2s_active>, <&pri_mi2s_active>, <&pri_mi2s_mclk_active>;
#address-cells = <1>;
#size-cells = <0>;
dai-link@0 {
reg = <MI2S_PRIMARY>;
qcom,playback-sd-lines = <1>;
qcom,capture-sd-lines = <0>;
};
secondary_mi2s: dai-link@1 {
reg = <MI2S_SECONDARY>;
qcom,playback-sd-lines = <0>;
};
dai-link@5 {
reg = <LPASS_DP_RX>;
};
};
&lpass_hm {
status = "okay";
};
&mdss {
status = "okay";
};
&mdss_dp {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&dp_hot_plug_det>;
};
&mdss_dp_out {
data-lanes = <0 1>;
link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000>;
};
&mdss_dsi0 {
status = "okay";
vdda-supply = <&vdda_mipi_dsi0_1p2>;
};
&mdss_dsi0_out {
data-lanes = <0 1 2 3>;
};
&mdss_dsi0_phy {
status = "okay";
vdds-supply = <&vdda_mipi_dsi0_pll>;
};
&pm6150_adc {
channel@4f {
reg = <ADC5_AMUX_THM3_100K_PU>;
qcom,ratiometric;
qcom,hw-settle-time = <200>;
label = "charger_therm";
};
};
&pm6150_adc_tm {
status = "okay";
charger-thermistor@0 {
reg = <0>;
io-channels = <&pm6150_adc ADC5_AMUX_THM3_100K_PU>;
qcom,ratiometric;
qcom,hw-settle-time-us = <200>;
};
};
&pm6150_pon {
status = "disabled";
};
&qupv3_id_0 {
status = "okay";
};
&qupv3_id_1 {
status = "okay";
};
&remoteproc_mpss {
status = "okay";
compatible = "qcom,sc7180-mss-pil";
reg = <0 0x04080000 0 0x4040>, <0 0x04180000 0 0x48>;
reg-names = "qdsp6", "rmb";
clocks = <&gcc GCC_MSS_CFG_AHB_CLK>,
<&gcc GCC_MSS_Q6_MEMNOC_AXI_CLK>,
<&gcc GCC_MSS_NAV_AXI_CLK>,
<&gcc GCC_MSS_SNOC_AXI_CLK>,
<&gcc GCC_MSS_MFAB_AXIS_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "bus", "nav", "snoc_axi", "mnoc_axi", "xo";
iommus = <&apps_smmu 0x461 0x0>, <&apps_smmu 0x444 0x3>;
memory-region = <&mba_mem>, <&mpss_mem>, <&mdata_mem>;
/* This gets overridden for SKUs with LTE support. */
firmware-name = "qcom/sc7180-trogdor/modem-nolte/mba.mbn",
"qcom/sc7180-trogdor/modem-nolte/qdsp6sw.mbn";
resets = <&aoss_reset AOSS_CC_MSS_RESTART>,
<&pdc_reset PDC_MODEM_SYNC_RESET>;
reset-names = "mss_restart", "pdc_reset";
qcom,halt-regs = <&tcsr_regs_1 0x3000 0x5000 0x4000>;
qcom,spare-regs = <&tcsr_regs_2 0xb3e4>;
};
arm64: dts: qcom: sc7180: Mark SCM as dma-coherent for trogdor Trogdor devices use firmware backed by TF-A instead of Qualcomm's normal TZ. On TF-A we end up mapping memory as cacheable. Specifically, you can see in Trogdor's TF-A code [1] in qti_sip_mem_assign() that we call qti_mmap_add_dynamic_region() with MT_RO_DATA. This translates down to MT_MEMORY instead of MT_NON_CACHEABLE or MT_DEVICE. Apparently Qualcomm's normal TZ implementation maps the memory as non-cacheable. Let's add the "dma-coherent" attribute to the SCM for trogdor. Adding "dma-coherent" like this fixes WiFi on sc7180-trogdor devices. WiFi was broken as of commit 7bd6680b47fa ("Revert "Revert "arm64: dma: Drop cache invalidation from arch_dma_prep_coherent()"""). Specifically at bootup we'd get: qcom_scm firmware:scm: Assign memory protection call failed -22 qcom_rmtfs_mem 94600000.memory: assign memory failed qcom_rmtfs_mem: probe of 94600000.memory failed with error -22 From discussion on the mailing lists [2] and over IRC [3], it was determined that we should always have been tagging the SCM as dma-coherent on trogdor but that the old "invalidate" happened to make things work most of the time. Tagging it properly like this is a much more robust solution. [1] https://chromium.googlesource.com/chromiumos/third_party/arm-trusted-firmware/+/refs/heads/firmware-trogdor-13577.B/plat/qti/common/src/qti_syscall.c [2] https://lore.kernel.org/r/20230614165904.1.I279773c37e2c1ed8fbb622ca6d1397aea0023526@changeid [3] https://oftc.irclog.whitequark.org/linux-msm/2023-06-15 Fixes: 7bd6680b47fa ("Revert "Revert "arm64: dma: Drop cache invalidation from arch_dma_prep_coherent()""") Fixes: 7ec3e67307f8 ("arm64: dts: qcom: sc7180-trogdor: add initial trogdor and lazor dt") Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://lore.kernel.org/r/20230616081440.v2.3.Ic62daa649b47b656b313551d646c4de9a7da4bd4@changeid Signed-off-by: Bjorn Andersson <andersson@kernel.org>
2023-06-16 15:14:40 +00:00
&scm {
/* TF-A firmware maps memory cached so mark dma-coherent to match. */
dma-coherent;
};
&sdhc_1 {
status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sdc1_on>;
pinctrl-1 = <&sdc1_off>;
vmmc-supply = <&mcp_vcc>;
vqmmc-supply = <&mcp_vccq>;
};
&sdhc_2 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sdc2_on>;
pinctrl-1 = <&sdc2_off>;
vmmc-supply = <&pp2950_l9c>;
vqmmc-supply = <&ppvar_l6c>;
cd-gpios = <&tlmm 69 GPIO_ACTIVE_LOW>;
};
&spi0 {
pinctrl-0 = <&qup_spi0_spi>, <&qup_spi0_cs_gpio>;
cs-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
};
&spi6 {
pinctrl-0 = <&qup_spi6_spi>, <&qup_spi6_cs_gpio>;
cs-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
};
ap_spi_fp: &spi10 {
pinctrl-0 = <&qup_spi10_spi>, <&qup_spi10_cs_gpio>;
cs-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>;
cros_ec_fp: ec@0 {
compatible = "google,cros-ec-fp", "google,cros-ec-spi";
reg = <0>;
interrupt-parent = <&tlmm>;
interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&fp_to_ap_irq_l>, <&fp_rst_l>, <&fpmcu_boot0>;
boot0-gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>;
reset-gpios = <&tlmm 22 GPIO_ACTIVE_LOW>;
spi-max-frequency = <3000000>;
vdd-supply = <&pp3300_fp_tp>;
};
};
#include <arm/cros-ec-sbs.dtsi>
&uart3 {
status = "okay";
/delete-property/interrupts;
interrupts-extended = <&intc GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>,
<&tlmm 41 IRQ_TYPE_EDGE_FALLING>;
pinctrl-names = "default", "sleep";
pinctrl-1 = <&qup_uart3_sleep>;
bluetooth: bluetooth {
compatible = "qcom,wcn3991-bt";
vddio-supply = <&pp1800_l10a>;
vddxo-supply = <&pp1800_l1c>;
vddrf-supply = <&pp1300_l2c>;
vddch0-supply = <&pp3300_l10c>;
max-speed = <3200000>;
qcom,local-bd-address-broken;
};
};
&uart8 {
status = "okay";
};
&usb_1 {
status = "okay";
};
&usb_1_dwc3 {
dr_mode = "host";
#address-cells = <1>;
#size-cells = <0>;
/* 2.x hub on port 1 */
usb_hub_2_x: hub@1 {
compatible = "usbbda,5411";
reg = <1>;
vdd-supply = <&pp3300_hub>;
peer-hub = <&usb_hub_3_x>;
};
/* 3.x hub on port 2 */
usb_hub_3_x: hub@2 {
compatible = "usbbda,411";
reg = <2>;
vdd-supply = <&pp3300_hub>;
peer-hub = <&usb_hub_2_x>;
};
};
&usb_1_hsphy {
status = "okay";
vdd-supply = <&vdd_qusb_hs0_core>;
vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
qcom,imp-res-offset-value = <8>;
qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_15_PERCENT>;
qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>;
qcom,bias-ctrl-value = <0x22>;
qcom,charge-ctrl-value = <3>;
qcom,hsdisc-trim-value = <0>;
};
&usb_1_qmpphy {
status = "okay";
vdda-phy-supply = <&vdda_usb_ss_dp_1p2>;
vdda-pll-supply = <&vdda_usb_ss_dp_core>;
};
&venus {
video-firmware {
iommus = <&apps_smmu 0x0c42 0x0>;
};
};
&wifi {
status = "okay";
vdd-0.8-cx-mx-supply = <&vdd_cx_wlan>;
vdd-1.8-xo-supply = <&pp1800_l1c>;
vdd-1.3-rfa-supply = <&pp1300_l2c>;
vdd-3.3-ch0-supply = <&pp3300_l10c>;
vdd-3.3-ch1-supply = <&pp3300_l11c>;
wifi-firmware {
iommus = <&apps_smmu 0xc2 0x1>;
};
};
/* PINCTRL - additions to nodes defined in sc7180.dtsi */
&dp_hot_plug_det {
bias-disable;
};
&pri_mi2s_active {
drive-strength = <2>;
bias-pull-down;
};
&pri_mi2s_mclk_active {
drive-strength = <2>;
bias-pull-down;
};
&qspi_cs0 {
arm64: dts: qcom: sc7180: Fix trogdor qspi pin config In commit 7ec3e67307f8 ("arm64: dts: qcom: sc7180-trogdor: add initial trogdor and lazor dt") we specified the pull settings on the boot SPI (the qspi) data lines as pullups to "park" the lines. This seemed like the right thing to do, but I never really probed the lines to confirm. Since that time, I've done A LOT of research, experiements and poking of the lines with a voltmeter. A first batch of discoveries: - There is an external pullup on CS (clearly shown on schematics) - There are weak external pulldowns on CLK/MOSI (believed to be Cr50's internal pulldowns) - There is no pull on MISO. - When qspi isn't actively transferring it still drives CS, CLK, and MOSI. CS and MOSI are driven high and CLK is driven low. It does not drive MISO and (if no internal pulls are enabled) the line floats. The above means that it's good to have some sort of pull on MISO, at the very least. The pullup that we had before was actually fine (and my voltmeter confirms that it actually affected the state of the pin) but a pulldown would work equally well (and would match MOSI and CLK better). The above also means that we could save a tiny bit of power (not measurable by my setup) by setting up a sleep state for these pins. If nothing else this prevents us from driving high against Cr50's internal pulldown on MOSI. However, Qualcomm has also asserted in the past that it burns a little extra power to drive a pin, especially since these are configured with a slightly higher drive strength Let's fix all this. Since the external pulls are different for the two data lines, we'll split them into separate configs. Then we'll change the MISO pin to a pulldown and add a sleep state. On a slightly tangental (but not totally unrelated note), I also discovered some interesting things with these pins in suspend. First, I found that if we don't switch the pins to GPIO that the qspi peripheral continues to drive them in suspend. That'll be solved by what we're already doing above. Second, I found that something in the system suspend path (after Linux stops running) reconfigures these pins so that they don't have their normal pulls enabled but instead change to "keepers" (bias-bus-hold in DT speak). If a pin was floating before we entered suspend then it would stop floating. I found that I could manually pull a pin to a different level and then probe it and it would stay there. This is exactly keeper behavior. With the solution we have the switch to "keeper" doesn't matter too much but it's good to document. While talking about "keepers", it can also be noted that I found that the "keepers" on these pins were at least enough to win a fight against Cr50's internal pulls. That means it's best to make sure that the state of the pins are already correct before the mysterious transition to a keeper. Otherwise we'll burn (a small amount of) power in S3 via this fight. Luckily with the current solution we don't hit this case. NOTE: I've left "sc7180-idp" behavior totally alone in this patch. I didn't add a sleep state and I didn't change any pulls--I just adapted it to the fact that the data lines have separate configs. Qualcomm doesn't provide me with schematics for IDP and thus I don't actually know how the pulls are configured. Since this is just a development platform and worked well enough, it seems safer to leave it alone. Dependencies: - This patch has a hard dependency on ("pinctrl: qcom: Support OUTPUT_ENABLE; deprecate INPUT_ENABLE"). Something in the boot code seemed to have been confused and thought it needed to set the "OUTPUT ENABLE" bit for these pins even though it was using them as SPI. Thus if we don't honor the "output-disable" property we could end up driving the SPI pins while in sleep mode. - In general, it's probably best not to backport this to a kernel that doesn't have commit d21f4b7ffc22 ("pinctrl: qcom: Avoid glitching lines when we first mux to output"). That landed a while ago, but it's still good to be explicit in case someone was backporting. If we don't have that then there might be a glitch when we first switch over to GPIO before we disable the output. - This patch _doesn't_ really have any dependency on the qspi driver patch that supports setting the pinctrl sleep state--they can go in either order. If we define the sleep state and the driver never selects it that's fine. If the driver tries to select a sleep state that we don't define that's fine. Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Bjorn Andersson <andersson@kernel.org> Link: https://lore.kernel.org/r/20230323102605.12.I6f03f86546e6ce9abb1d24fd9ece663c3a5b950c@changeid
2023-03-23 17:30:16 +00:00
bias-disable; /* External pullup */
};
&qspi_clk {
drive-strength = <8>;
arm64: dts: qcom: sc7180: Fix trogdor qspi pin config In commit 7ec3e67307f8 ("arm64: dts: qcom: sc7180-trogdor: add initial trogdor and lazor dt") we specified the pull settings on the boot SPI (the qspi) data lines as pullups to "park" the lines. This seemed like the right thing to do, but I never really probed the lines to confirm. Since that time, I've done A LOT of research, experiements and poking of the lines with a voltmeter. A first batch of discoveries: - There is an external pullup on CS (clearly shown on schematics) - There are weak external pulldowns on CLK/MOSI (believed to be Cr50's internal pulldowns) - There is no pull on MISO. - When qspi isn't actively transferring it still drives CS, CLK, and MOSI. CS and MOSI are driven high and CLK is driven low. It does not drive MISO and (if no internal pulls are enabled) the line floats. The above means that it's good to have some sort of pull on MISO, at the very least. The pullup that we had before was actually fine (and my voltmeter confirms that it actually affected the state of the pin) but a pulldown would work equally well (and would match MOSI and CLK better). The above also means that we could save a tiny bit of power (not measurable by my setup) by setting up a sleep state for these pins. If nothing else this prevents us from driving high against Cr50's internal pulldown on MOSI. However, Qualcomm has also asserted in the past that it burns a little extra power to drive a pin, especially since these are configured with a slightly higher drive strength Let's fix all this. Since the external pulls are different for the two data lines, we'll split them into separate configs. Then we'll change the MISO pin to a pulldown and add a sleep state. On a slightly tangental (but not totally unrelated note), I also discovered some interesting things with these pins in suspend. First, I found that if we don't switch the pins to GPIO that the qspi peripheral continues to drive them in suspend. That'll be solved by what we're already doing above. Second, I found that something in the system suspend path (after Linux stops running) reconfigures these pins so that they don't have their normal pulls enabled but instead change to "keepers" (bias-bus-hold in DT speak). If a pin was floating before we entered suspend then it would stop floating. I found that I could manually pull a pin to a different level and then probe it and it would stay there. This is exactly keeper behavior. With the solution we have the switch to "keeper" doesn't matter too much but it's good to document. While talking about "keepers", it can also be noted that I found that the "keepers" on these pins were at least enough to win a fight against Cr50's internal pulls. That means it's best to make sure that the state of the pins are already correct before the mysterious transition to a keeper. Otherwise we'll burn (a small amount of) power in S3 via this fight. Luckily with the current solution we don't hit this case. NOTE: I've left "sc7180-idp" behavior totally alone in this patch. I didn't add a sleep state and I didn't change any pulls--I just adapted it to the fact that the data lines have separate configs. Qualcomm doesn't provide me with schematics for IDP and thus I don't actually know how the pulls are configured. Since this is just a development platform and worked well enough, it seems safer to leave it alone. Dependencies: - This patch has a hard dependency on ("pinctrl: qcom: Support OUTPUT_ENABLE; deprecate INPUT_ENABLE"). Something in the boot code seemed to have been confused and thought it needed to set the "OUTPUT ENABLE" bit for these pins even though it was using them as SPI. Thus if we don't honor the "output-disable" property we could end up driving the SPI pins while in sleep mode. - In general, it's probably best not to backport this to a kernel that doesn't have commit d21f4b7ffc22 ("pinctrl: qcom: Avoid glitching lines when we first mux to output"). That landed a while ago, but it's still good to be explicit in case someone was backporting. If we don't have that then there might be a glitch when we first switch over to GPIO before we disable the output. - This patch _doesn't_ really have any dependency on the qspi driver patch that supports setting the pinctrl sleep state--they can go in either order. If we define the sleep state and the driver never selects it that's fine. If the driver tries to select a sleep state that we don't define that's fine. Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Bjorn Andersson <andersson@kernel.org> Link: https://lore.kernel.org/r/20230323102605.12.I6f03f86546e6ce9abb1d24fd9ece663c3a5b950c@changeid
2023-03-23 17:30:16 +00:00
bias-disable; /* Rely on Cr50 internal pulldown */
};
arm64: dts: qcom: sc7180: Fix trogdor qspi pin config In commit 7ec3e67307f8 ("arm64: dts: qcom: sc7180-trogdor: add initial trogdor and lazor dt") we specified the pull settings on the boot SPI (the qspi) data lines as pullups to "park" the lines. This seemed like the right thing to do, but I never really probed the lines to confirm. Since that time, I've done A LOT of research, experiements and poking of the lines with a voltmeter. A first batch of discoveries: - There is an external pullup on CS (clearly shown on schematics) - There are weak external pulldowns on CLK/MOSI (believed to be Cr50's internal pulldowns) - There is no pull on MISO. - When qspi isn't actively transferring it still drives CS, CLK, and MOSI. CS and MOSI are driven high and CLK is driven low. It does not drive MISO and (if no internal pulls are enabled) the line floats. The above means that it's good to have some sort of pull on MISO, at the very least. The pullup that we had before was actually fine (and my voltmeter confirms that it actually affected the state of the pin) but a pulldown would work equally well (and would match MOSI and CLK better). The above also means that we could save a tiny bit of power (not measurable by my setup) by setting up a sleep state for these pins. If nothing else this prevents us from driving high against Cr50's internal pulldown on MOSI. However, Qualcomm has also asserted in the past that it burns a little extra power to drive a pin, especially since these are configured with a slightly higher drive strength Let's fix all this. Since the external pulls are different for the two data lines, we'll split them into separate configs. Then we'll change the MISO pin to a pulldown and add a sleep state. On a slightly tangental (but not totally unrelated note), I also discovered some interesting things with these pins in suspend. First, I found that if we don't switch the pins to GPIO that the qspi peripheral continues to drive them in suspend. That'll be solved by what we're already doing above. Second, I found that something in the system suspend path (after Linux stops running) reconfigures these pins so that they don't have their normal pulls enabled but instead change to "keepers" (bias-bus-hold in DT speak). If a pin was floating before we entered suspend then it would stop floating. I found that I could manually pull a pin to a different level and then probe it and it would stay there. This is exactly keeper behavior. With the solution we have the switch to "keeper" doesn't matter too much but it's good to document. While talking about "keepers", it can also be noted that I found that the "keepers" on these pins were at least enough to win a fight against Cr50's internal pulls. That means it's best to make sure that the state of the pins are already correct before the mysterious transition to a keeper. Otherwise we'll burn (a small amount of) power in S3 via this fight. Luckily with the current solution we don't hit this case. NOTE: I've left "sc7180-idp" behavior totally alone in this patch. I didn't add a sleep state and I didn't change any pulls--I just adapted it to the fact that the data lines have separate configs. Qualcomm doesn't provide me with schematics for IDP and thus I don't actually know how the pulls are configured. Since this is just a development platform and worked well enough, it seems safer to leave it alone. Dependencies: - This patch has a hard dependency on ("pinctrl: qcom: Support OUTPUT_ENABLE; deprecate INPUT_ENABLE"). Something in the boot code seemed to have been confused and thought it needed to set the "OUTPUT ENABLE" bit for these pins even though it was using them as SPI. Thus if we don't honor the "output-disable" property we could end up driving the SPI pins while in sleep mode. - In general, it's probably best not to backport this to a kernel that doesn't have commit d21f4b7ffc22 ("pinctrl: qcom: Avoid glitching lines when we first mux to output"). That landed a while ago, but it's still good to be explicit in case someone was backporting. If we don't have that then there might be a glitch when we first switch over to GPIO before we disable the output. - This patch _doesn't_ really have any dependency on the qspi driver patch that supports setting the pinctrl sleep state--they can go in either order. If we define the sleep state and the driver never selects it that's fine. If the driver tries to select a sleep state that we don't define that's fine. Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Bjorn Andersson <andersson@kernel.org> Link: https://lore.kernel.org/r/20230323102605.12.I6f03f86546e6ce9abb1d24fd9ece663c3a5b950c@changeid
2023-03-23 17:30:16 +00:00
&qspi_data0 {
bias-disable; /* Rely on Cr50 internal pulldown */
};
&qspi_data1 {
bias-pull-down;
};
&qup_i2c2_default {
drive-strength = <2>;
/* Has external pullup */
bias-disable;
};
&qup_i2c4_default {
drive-strength = <2>;
/* Has external pullup */
bias-disable;
};
&qup_i2c5_default {
drive-strength = <2>;
/* Has external pullup */
bias-disable;
};
&qup_i2c7_default {
drive-strength = <2>;
/* Has external pullup */
bias-disable;
};
&qup_i2c9_default {
drive-strength = <2>;
/* Has external pullup */
bias-disable;
};
&qup_spi0_spi {
drive-strength = <2>;
bias-disable;
};
&qup_spi0_cs_gpio {
drive-strength = <2>;
bias-disable;
};
&qup_spi6_spi {
drive-strength = <2>;
bias-disable;
};
&qup_spi6_cs_gpio {
drive-strength = <2>;
bias-disable;
};
&qup_spi10_spi {
drive-strength = <2>;
bias-disable;
};
&qup_spi10_cs_gpio {
drive-strength = <2>;
bias-disable;
};
&qup_uart3_cts {
/*
* Configure a pull-down on CTS to match the pull of
* the Bluetooth module.
*/
bias-pull-down;
};
&qup_uart3_rts {
/* We'll drive RTS, so no pull */
drive-strength = <2>;
bias-disable;
};
&qup_uart3_tx {
/* We'll drive TX, so no pull */
drive-strength = <2>;
bias-disable;
};
&qup_uart3_rx {
/*
* Configure a pull-up on RX. This is needed to avoid
* garbage data when the TX pin of the Bluetooth module is
* in tri-state (module powered off or not driving the
* signal yet).
*/
bias-pull-up;
};
&qup_uart8_tx {
drive-strength = <2>;
bias-disable;
};
&qup_uart8_rx {
drive-strength = <2>;
bias-pull-up;
};
&sec_mi2s_active {
drive-strength = <2>;
bias-pull-down;
};
/* PINCTRL - board-specific pinctrl */
&pm6150_gpios {
status = "disabled"; /* No GPIOs are connected */
};
&pm6150l_gpios {
gpio-line-names = "AP_SUSPEND",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"";
};
&tlmm {
/*
* pinctrl settings for pins that have no real owners.
*/
pinctrl-names = "default";
pinctrl-0 = <&bios_flash_wp_l>, <&ap_suspend_l_neuter>;
amp_en: amp-en-state {
pins = "gpio23";
function = "gpio";
bias-pull-down;
};
ap_ec_int_l: ap-ec-int-l-state {
pins = "gpio94";
function = "gpio";
bias-pull-up;
};
ap_edp_bklten: ap-edp-bklten-state {
pins = "gpio12";
function = "gpio";
drive-strength = <2>;
bias-disable;
/* Force backlight to be disabled to match state at boot. */
output-low;
};
ap_suspend_l_neuter: ap-suspend-l-neuter-state {
pins = "gpio27";
function = "gpio";
bias-disable;
};
bios_flash_wp_l: bios-flash-wp-l-state {
pins = "gpio66";
function = "gpio";
bias-disable;
};
edp_brij_en: edp-brij-en-state {
pins = "gpio104";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
en_pp3300_codec: en-pp3300-codec-state {
pins = "gpio83";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
en_pp3300_dx_edp: en-pp3300-dx-edp-state {
pins = "gpio30";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
en_pp3300_hub: en-pp3300-hub-state {
pins = "gpio84";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
fp_rst_l: fp-rst-l-state {
pins = "gpio22";
function = "gpio";
bias-disable;
drive-strength = <2>;
};
fp_to_ap_irq_l: fp-to-ap-irq-l-state {
pins = "gpio4";
function = "gpio";
/* Has external pullup */
bias-disable;
};
fpmcu_boot0: fpmcu-boot0-state {
pins = "gpio10";
function = "gpio";
bias-disable;
};
h1_ap_int_odl: h1-ap-int-odl-state {
pins = "gpio42";
function = "gpio";
bias-pull-up;
};
hp_irq: hp-irq-state {
pins = "gpio28";
function = "gpio";
bias-pull-up;
};
pen_irq_l: pen-irq-l-state {
pins = "gpio21";
function = "gpio";
/* Has external pullup */
bias-disable;
};
pen_pdct_l: pen-pdct-l-state-state {
pins = "gpio52";
function = "gpio";
/* Has external pullup */
bias-disable;
};
pen_rst_odl: pen-rst-odl-state {
pins = "gpio18";
function = "gpio";
bias-disable;
drive-strength = <2>;
/*
* The pen driver doesn't currently support
* driving this reset line. By specifying
* output-high here we're relying on the fact
* that this pin has a default pulldown at boot
* (which makes sure the pen was in reset if it
* was powered) and then we set it high here to
* take it out of reset. Better would be if the
* pen driver could control this and we could
* remove "output-high" here.
*/
output-high; /* TODO: Remove this? */
};
p_sensor_int_l: p-sensor-int-l-state {
pins = "gpio24";
function = "gpio";
/* Has external pullup */
bias-disable;
};
arm64: dts: qcom: sc7180: Fix trogdor qspi pin config In commit 7ec3e67307f8 ("arm64: dts: qcom: sc7180-trogdor: add initial trogdor and lazor dt") we specified the pull settings on the boot SPI (the qspi) data lines as pullups to "park" the lines. This seemed like the right thing to do, but I never really probed the lines to confirm. Since that time, I've done A LOT of research, experiements and poking of the lines with a voltmeter. A first batch of discoveries: - There is an external pullup on CS (clearly shown on schematics) - There are weak external pulldowns on CLK/MOSI (believed to be Cr50's internal pulldowns) - There is no pull on MISO. - When qspi isn't actively transferring it still drives CS, CLK, and MOSI. CS and MOSI are driven high and CLK is driven low. It does not drive MISO and (if no internal pulls are enabled) the line floats. The above means that it's good to have some sort of pull on MISO, at the very least. The pullup that we had before was actually fine (and my voltmeter confirms that it actually affected the state of the pin) but a pulldown would work equally well (and would match MOSI and CLK better). The above also means that we could save a tiny bit of power (not measurable by my setup) by setting up a sleep state for these pins. If nothing else this prevents us from driving high against Cr50's internal pulldown on MOSI. However, Qualcomm has also asserted in the past that it burns a little extra power to drive a pin, especially since these are configured with a slightly higher drive strength Let's fix all this. Since the external pulls are different for the two data lines, we'll split them into separate configs. Then we'll change the MISO pin to a pulldown and add a sleep state. On a slightly tangental (but not totally unrelated note), I also discovered some interesting things with these pins in suspend. First, I found that if we don't switch the pins to GPIO that the qspi peripheral continues to drive them in suspend. That'll be solved by what we're already doing above. Second, I found that something in the system suspend path (after Linux stops running) reconfigures these pins so that they don't have their normal pulls enabled but instead change to "keepers" (bias-bus-hold in DT speak). If a pin was floating before we entered suspend then it would stop floating. I found that I could manually pull a pin to a different level and then probe it and it would stay there. This is exactly keeper behavior. With the solution we have the switch to "keeper" doesn't matter too much but it's good to document. While talking about "keepers", it can also be noted that I found that the "keepers" on these pins were at least enough to win a fight against Cr50's internal pulls. That means it's best to make sure that the state of the pins are already correct before the mysterious transition to a keeper. Otherwise we'll burn (a small amount of) power in S3 via this fight. Luckily with the current solution we don't hit this case. NOTE: I've left "sc7180-idp" behavior totally alone in this patch. I didn't add a sleep state and I didn't change any pulls--I just adapted it to the fact that the data lines have separate configs. Qualcomm doesn't provide me with schematics for IDP and thus I don't actually know how the pulls are configured. Since this is just a development platform and worked well enough, it seems safer to leave it alone. Dependencies: - This patch has a hard dependency on ("pinctrl: qcom: Support OUTPUT_ENABLE; deprecate INPUT_ENABLE"). Something in the boot code seemed to have been confused and thought it needed to set the "OUTPUT ENABLE" bit for these pins even though it was using them as SPI. Thus if we don't honor the "output-disable" property we could end up driving the SPI pins while in sleep mode. - In general, it's probably best not to backport this to a kernel that doesn't have commit d21f4b7ffc22 ("pinctrl: qcom: Avoid glitching lines when we first mux to output"). That landed a while ago, but it's still good to be explicit in case someone was backporting. If we don't have that then there might be a glitch when we first switch over to GPIO before we disable the output. - This patch _doesn't_ really have any dependency on the qspi driver patch that supports setting the pinctrl sleep state--they can go in either order. If we define the sleep state and the driver never selects it that's fine. If the driver tries to select a sleep state that we don't define that's fine. Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Bjorn Andersson <andersson@kernel.org> Link: https://lore.kernel.org/r/20230323102605.12.I6f03f86546e6ce9abb1d24fd9ece663c3a5b950c@changeid
2023-03-23 17:30:16 +00:00
qspi_sleep: qspi-sleep-state {
pins = "gpio63", "gpio64", "gpio65", "gpio68";
/*
* When we're not actively transferring we want pins as GPIOs
* with output disabled so that the quad SPI IP block stops
* driving them. We rely on the normal pulls configured in
* the active state and don't redefine them here. Also note
* that we don't need the reverse (output-enable) in the
* normal mode since the "output-enable" only matters for
* GPIO function.
*/
function = "gpio";
output-disable;
};
qup_uart3_sleep: qup-uart3-sleep-state {
cts-pins {
/*
* Configure a pull-down on CTS to match the pull of
* the Bluetooth module.
*/
pins = "gpio38";
function = "gpio";
bias-pull-down;
};
rts-pins {
/*
* Configure pull-down on RTS. As RTS is active low
* signal, pull it low to indicate the BT SoC that it
* can wakeup the system anytime from suspend state by
* pulling RX low (by sending wakeup bytes).
*/
pins = "gpio39";
function = "gpio";
bias-pull-down;
};
tx-pins {
/*
* Configure pull-up on TX when it isn't actively driven
* to prevent BT SoC from receiving garbage during sleep.
*/
pins = "gpio40";
function = "gpio";
bias-pull-up;
};
rx-pins {
/*
* Configure a pull-up on RX. This is needed to avoid
* garbage data when the TX pin of the Bluetooth module
* is floating which may cause spurious wakeups.
*/
pins = "gpio41";
function = "gpio";
bias-pull-up;
};
};
/* Named trackpad_int_1v8_odl on earlier revision schematics */
trackpad_int_1v8_odl:
tp_int_odl: tp-int-odl-state {
pins = "gpio0";
function = "gpio";
/* Has external pullup */
bias-disable;
};
ts_int_l: ts-int-l-state {
pins = "gpio9";
function = "gpio";
bias-pull-up;
};
ts_reset_l: ts-reset-l-state {
pins = "gpio8";
function = "gpio";
bias-disable;
/*
* The reset GPIO to the touchscreen takes almost 2ms to drop
* at the default drive strength. When we bump it up to 8mA it
* falls in under 500us. We want this to be fast since the Elan
* datasheet (and any drivers written based on it) talk about using
* a 500 us reset pulse.
*/
drive-strength = <8>;
};
sdc1_on: sdc1-on-state {
clk-pins {
pins = "sdc1_clk";
bias-disable;
drive-strength = <16>;
};
cmd-pins {
pins = "sdc1_cmd";
bias-pull-up;
drive-strength = <16>;
};
data-pins {
pins = "sdc1_data";
bias-pull-up;
drive-strength = <16>;
};
rclk-pins {
pins = "sdc1_rclk";
bias-pull-down;
};
};
sdc1_off: sdc1-off-state {
clk-pins {
pins = "sdc1_clk";
bias-disable;
drive-strength = <2>;
};
cmd-pins {
pins = "sdc1_cmd";
bias-pull-up;
drive-strength = <2>;
};
data-pins {
pins = "sdc1_data";
bias-pull-up;
drive-strength = <2>;
};
rclk-pins {
pins = "sdc1_rclk";
bias-pull-down;
};
};
sdc2_on: sdc2-on-state {
clk-pins {
pins = "sdc2_clk";
bias-disable;
drive-strength = <16>;
};
cmd-pins {
pins = "sdc2_cmd";
bias-pull-up;
drive-strength = <10>;
};
data-pins {
pins = "sdc2_data";
bias-pull-up;
drive-strength = <10>;
};
sd-cd-pins {
pins = "gpio69";
function = "gpio";
bias-pull-up;
drive-strength = <2>;
};
};
sdc2_off: sdc2-off-state {
clk-pins {
pins = "sdc2_clk";
bias-disable;
drive-strength = <2>;
};
cmd-pins {
pins = "sdc2_cmd";
bias-pull-up;
drive-strength = <2>;
};
data-pins {
pins = "sdc2_data";
bias-pull-up;
drive-strength = <2>;
};
sd-cd-pins {
pins = "gpio69";
function = "gpio";
bias-pull-up;
drive-strength = <2>;
};
};
uf_cam_en: uf-cam-en-state {
pins = "gpio6";
function = "gpio";
drive-strength = <2>;
/* External pull down */
bias-disable;
};
wf_cam_en: wf-cam-en-state {
pins = "gpio7";
function = "gpio";
drive-strength = <2>;
/* External pull down */
bias-disable;
};
};