WCN3990 and other similar WiFi/BT chips incorporate a simple on-chip PMU (clearly described as such in the documentation). Extend DT schema covering other Qualcomm WiFi/BT chips to cover these devices too. Signed-off-by: Dmitry Baryshkov --- .../bindings/regulator/qcom,qca6390-pmu.yaml | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml b/Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml index 47c425c9fff1..dc88523f46f8 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml @@ -18,6 +18,11 @@ properties: compatible: enum: - qcom,qca6390-pmu + - qcom,wcn3950-pmu + - qcom,wcn3988-pmu + - qcom,wcn3990-pmu + - qcom,wcn3991-pmu + - qcom,wcn3998-pmu - qcom,wcn6750-pmu - qcom,wcn6855-pmu - qcom,wcn7850-pmu @@ -76,9 +81,18 @@ properties: vddpcie1p9-supply: description: VDD_PCIE_1P9 supply regulator handle + vddch0-supply: + description: chain 0 supply regulator handle + + vddch1-supply: + description: chain 1 supply regulator handle + vddio-supply: description: VDD_IO supply regulator handle + vddxo-supply: + description: VDD_XTAL supply regulator handle + wlan-enable-gpios: maxItems: 1 description: GPIO line enabling the ATH11K WLAN module supplied by the PMU @@ -132,6 +146,28 @@ allOf: - vddpcie1p3-supply - vddpcie1p9-supply - vddio-supply + + - if: + properties: + compatible: + contains: + enum: + - qcom,wcn3950-pmu + - qcom,wcn3988-pmu + - qcom,wcn3990-pmu + - qcom,wcn3991-pmu + - qcom,wcn3998-pmu + then: + properties: + wlan-enable-gpios: false + bt-enable-gpios: false + required: + - vddio-supply + - vddxo-supply + - vddrfa1p3-supply + - vddch0-supply + - vddch1-supply + - if: properties: compatible: -- 2.47.3 The WCN39xx family of WiFi/BT chips incorporates a simple PMU, spreading voltages over internal rails. Implement support for using powersequencer for this family of QCA devices in addition to using regulators. Signed-off-by: Dmitry Baryshkov --- drivers/bluetooth/hci_qca.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index b54350317a43..d1402a344063 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2230,6 +2230,18 @@ static void qca_power_shutdown(struct hci_uart *hu) qcadev = serdev_device_get_drvdata(hu->serdev); power = qcadev->bt_power; + switch (soc_type) { + case QCA_WCN3988: + case QCA_WCN3990: + case QCA_WCN3991: + case QCA_WCN3998: + host_set_baudrate(hu, 2400); + qca_send_power_pulse(hu, false); + break; + default: + break; + } + if (power && power->pwrseq) { pwrseq_power_off(power->pwrseq); set_bit(QCA_BT_OFF, &qca->flags); @@ -2241,8 +2253,6 @@ static void qca_power_shutdown(struct hci_uart *hu) case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: - host_set_baudrate(hu, 2400); - qca_send_power_pulse(hu, false); qca_regulator_disable(qcadev); break; @@ -2414,6 +2424,11 @@ static int qca_serdev_probe(struct serdev_device *serdev) } switch (qcadev->btsoc_type) { + case QCA_WCN3950: + case QCA_WCN3988: + case QCA_WCN3990: + case QCA_WCN3991: + case QCA_WCN3998: case QCA_WCN6855: case QCA_WCN7850: case QCA_WCN6750: @@ -2438,12 +2453,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) else break; } - fallthrough; - case QCA_WCN3950: - case QCA_WCN3988: - case QCA_WCN3990: - case QCA_WCN3991: - case QCA_WCN3998: + qcadev->bt_power->dev = &serdev->dev; err = qca_init_regulators(qcadev->bt_power, data->vregs, data->num_vregs); -- 2.47.3 WCN3998 uses a bit different format for rom version: [ 5.479978] Bluetooth: hci0: setting up wcn399x [ 5.633763] Bluetooth: hci0: QCA Product ID :0x0000000a [ 5.645350] Bluetooth: hci0: QCA SOC Version :0x40010224 [ 5.650906] Bluetooth: hci0: QCA ROM Version :0x00001001 [ 5.665173] Bluetooth: hci0: QCA Patch Version:0x00006699 [ 5.679356] Bluetooth: hci0: QCA controller version 0x02241001 [ 5.691109] Bluetooth: hci0: QCA Downloading qca/crbtfw21.tlv [ 6.680102] Bluetooth: hci0: QCA Downloading qca/crnv21.bin [ 6.842948] Bluetooth: hci0: QCA setup on UART is completed Fixes: 523760b7ff88 ("Bluetooth: hci_qca: Added support for WCN3998") Signed-off-by: Dmitry Baryshkov --- drivers/bluetooth/btqca.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 7c958d6065be..86a48d009d1b 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -804,6 +804,8 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, */ if (soc_type == QCA_WCN3988) rom_ver = ((soc_ver & 0x00000f00) >> 0x05) | (soc_ver & 0x0000000f); + else if (soc_type == QCA_WCN3998) + rom_ver = ((soc_ver & 0x0000f000) >> 0x07) | (soc_ver & 0x0000000f); else rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f); -- 2.47.3 The WCN39xx family of WiFi/BT chips incorporates a simple PMU, spreading voltages over internal rails. Implement support for using powersequencer for this family of ATH10k devices in addition to using regulators. Signed-off-by: Dmitry Baryshkov --- drivers/net/wireless/ath/ath10k/snoc.c | 43 +++++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath10k/snoc.h | 2 ++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index b3f6424c17d3..919d4b0b87cd 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -1023,9 +1024,15 @@ static int ath10k_hw_power_on(struct ath10k *ar) ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n"); + if (ar_snoc->pwrseq) { + ret = pwrseq_power_on(ar_snoc->pwrseq); + if (ret) + return ret; + } + ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); if (ret) - return ret; + goto pwrseq_off; ret = clk_bulk_prepare_enable(ar_snoc->num_clks, ar_snoc->clks); if (ret) @@ -1035,18 +1042,28 @@ static int ath10k_hw_power_on(struct ath10k *ar) vreg_off: regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); +pwrseq_off: + pwrseq_power_off(ar_snoc->pwrseq); + return ret; } static int ath10k_hw_power_off(struct ath10k *ar) { struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + int ret_seq = 0; + int ret_vreg; ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n"); clk_bulk_disable_unprepare(ar_snoc->num_clks, ar_snoc->clks); - return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); + ret_vreg = regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); + + if (ar_snoc->pwrseq) + ret_seq = pwrseq_power_off(ar_snoc->pwrseq); + + return ret_vreg ? : ret_seq; } static void ath10k_snoc_wlan_disable(struct ath10k *ar) @@ -1762,7 +1779,27 @@ static int ath10k_snoc_probe(struct platform_device *pdev) goto err_release_resource; } - ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators); + /* + * Backwards compatibility, ignore the defer error from pwrseq, if it + * should be used, we will get an error from regulator get. + */ + ar_snoc->pwrseq = devm_pwrseq_get(&pdev->dev, "wlan"); + if (IS_ERR(ar_snoc->pwrseq)) { + ret = PTR_ERR(ar_snoc->pwrseq); + ar_snoc->pwrseq = NULL; + if (ret != -EPROBE_DEFER) + goto err_free_irq; + + ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators); + } else { + /* + * The first regulator (vdd-0.8-cx-mx) is used to power on part + * of the SoC rather than the PMU on WCN399x, the rest are + * handled via pwrseq. + */ + ar_snoc->num_vregs = 1; + } + ar_snoc->vregs = devm_kcalloc(&pdev->dev, ar_snoc->num_vregs, sizeof(*ar_snoc->vregs), GFP_KERNEL); if (!ar_snoc->vregs) { diff --git a/drivers/net/wireless/ath/ath10k/snoc.h b/drivers/net/wireless/ath/ath10k/snoc.h index d4bce1707696..eeaa1c009cb0 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.h +++ b/drivers/net/wireless/ath/ath10k/snoc.h @@ -53,6 +53,7 @@ enum ath10k_snoc_flags { }; struct clk_bulk_data; +struct pwrseq_desc; struct regulator_bulk_data; struct ath10k_snoc { @@ -73,6 +74,7 @@ struct ath10k_snoc { struct ath10k_snoc_ce_irq ce_irqs[CE_COUNT_MAX]; struct ath10k_ce ce; struct timer_list rx_post_retry; + struct pwrseq_desc *pwrseq; struct regulator_bulk_data *vregs; size_t num_vregs; struct clk_bulk_data *clks; -- 2.47.3 The WCN39xx family of WiFi/BT chips incorporates a simple PMU, spreading voltages over internal rails. Implement power sequencing support for this generation of WCN chips. Unlike later devices, they don't have separate enable GPIO lines, letting the chip figure out the necessary parts on its own. Signed-off-by: Dmitry Baryshkov --- drivers/power/sequencing/pwrseq-qcom-wcn.c | 130 +++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 5 deletions(-) diff --git a/drivers/power/sequencing/pwrseq-qcom-wcn.c b/drivers/power/sequencing/pwrseq-qcom-wcn.c index 663d9a537065..ed81d0c90a2d 100644 --- a/drivers/power/sequencing/pwrseq-qcom-wcn.c +++ b/drivers/power/sequencing/pwrseq-qcom-wcn.c @@ -23,6 +23,8 @@ struct pwrseq_qcom_wcn_pdata { unsigned int pwup_delay_ms; unsigned int gpio_enable_delay_ms; const struct pwrseq_target_data **targets; + bool has_vddio; /* separate VDD IO regulator */ + int (*match)(struct pwrseq_device *pwrseq, struct device *dev); }; struct pwrseq_qcom_wcn_ctx { @@ -30,6 +32,7 @@ struct pwrseq_qcom_wcn_ctx { struct device_node *of_node; const struct pwrseq_qcom_wcn_pdata *pdata; struct regulator_bulk_data *regs; + struct regulator *vddio; struct gpio_desc *bt_gpio; struct gpio_desc *wlan_gpio; struct gpio_desc *xo_clk_gpio; @@ -52,6 +55,26 @@ static void pwrseq_qcom_wcn_ensure_gpio_delay(struct pwrseq_qcom_wcn_ctx *ctx) msleep(ctx->pdata->gpio_enable_delay_ms - diff_msecs); } +static int pwrseq_qcom_wcn_vddio_enable(struct pwrseq_device *pwrseq) +{ + struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + return regulator_enable(ctx->vddio); +} + +static int pwrseq_qcom_wcn_vddio_disable(struct pwrseq_device *pwrseq) +{ + struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + return regulator_disable(ctx->vddio); +} + +static const struct pwrseq_unit_data pwrseq_qcom_wcn_vddio_unit_data = { + .name = "vddio-enable", + .enable = pwrseq_qcom_wcn_vddio_enable, + .disable = pwrseq_qcom_wcn_vddio_disable, +}; + static int pwrseq_qcom_wcn_vregs_enable(struct pwrseq_device *pwrseq) { struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); @@ -94,6 +117,19 @@ static const struct pwrseq_unit_data pwrseq_qcom_wcn_clk_unit_data = { .disable = pwrseq_qcom_wcn_clk_disable, }; +static const struct pwrseq_unit_data *pwrseq_qcom_wcn3990_unit_deps[] = { + &pwrseq_qcom_wcn_vddio_unit_data, + &pwrseq_qcom_wcn_vregs_unit_data, + NULL, +}; + +static const struct pwrseq_unit_data pwrseq_qcom_wcn3990_unit_data = { + .name = "clock-enable", + .deps = pwrseq_qcom_wcn3990_unit_deps, + .enable = pwrseq_qcom_wcn_clk_enable, + .disable = pwrseq_qcom_wcn_clk_disable, +}; + static const struct pwrseq_unit_data *pwrseq_qcom_wcn_unit_deps[] = { &pwrseq_qcom_wcn_vregs_unit_data, &pwrseq_qcom_wcn_clk_unit_data, @@ -229,6 +265,17 @@ static const struct pwrseq_target_data pwrseq_qcom_wcn_wlan_target_data = { .post_enable = pwrseq_qcom_wcn_pwup_delay, }; +/* There are no separate BT and WLAN enablement pins */ +static const struct pwrseq_target_data pwrseq_qcom_wcn3990_bt_target_data = { + .name = "bluetooth", + .unit = &pwrseq_qcom_wcn3990_unit_data, +}; + +static const struct pwrseq_target_data pwrseq_qcom_wcn3990_wlan_target_data = { + .name = "wlan", + .unit = &pwrseq_qcom_wcn3990_unit_data, +}; + static const struct pwrseq_target_data pwrseq_qcom_wcn6855_bt_target_data = { .name = "bluetooth", .unit = &pwrseq_qcom_wcn6855_bt_unit_data, @@ -247,6 +294,12 @@ static const struct pwrseq_target_data *pwrseq_qcom_wcn_targets[] = { NULL }; +static const struct pwrseq_target_data *pwrseq_qcom_wcn3990_targets[] = { + &pwrseq_qcom_wcn3990_bt_target_data, + &pwrseq_qcom_wcn3990_wlan_target_data, + NULL +}; + static const struct pwrseq_target_data *pwrseq_qcom_wcn6855_targets[] = { &pwrseq_qcom_wcn6855_bt_target_data, &pwrseq_qcom_wcn6855_wlan_target_data, @@ -272,6 +325,26 @@ static const struct pwrseq_qcom_wcn_pdata pwrseq_qca6390_of_data = { .targets = pwrseq_qcom_wcn_targets, }; +static const char *const pwrseq_wcn3990_vregs[] = { + /* vddio is handled separately */ + "vddxo", + "vddrfa1p3", + "vddch0", + "vddch1", +}; + +static int pwrseq_qcom_wcn3990_match(struct pwrseq_device *pwrseq, + struct device *dev); + +static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn3990_of_data = { + .vregs = pwrseq_wcn3990_vregs, + .num_vregs = ARRAY_SIZE(pwrseq_wcn3990_vregs), + .pwup_delay_ms = 50, + .targets = pwrseq_qcom_wcn3990_targets, + .has_vddio = true, + .match = pwrseq_qcom_wcn3990_match, +}; + static const char *const pwrseq_wcn6750_vregs[] = { "vddaon", "vddasd", @@ -328,8 +401,9 @@ static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn7850_of_data = { .targets = pwrseq_qcom_wcn_targets, }; -static int pwrseq_qcom_wcn_match(struct pwrseq_device *pwrseq, - struct device *dev) +static int pwrseq_qcom_wcn_match_regulator(struct pwrseq_device *pwrseq, + struct device *dev, + const char *name) { struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); struct device_node *dev_node = dev->of_node; @@ -340,11 +414,11 @@ static int pwrseq_qcom_wcn_match(struct pwrseq_device *pwrseq, * 'vddaon-supply' property and whether it leads us to the right * device. */ - if (!of_property_present(dev_node, "vddaon-supply")) + if (!of_property_present(dev_node, name)) return PWRSEQ_NO_MATCH; struct device_node *reg_node __free(device_node) = - of_parse_phandle(dev_node, "vddaon-supply", 0); + of_parse_phandle(dev_node, name, 0); if (!reg_node) return PWRSEQ_NO_MATCH; @@ -360,6 +434,26 @@ static int pwrseq_qcom_wcn_match(struct pwrseq_device *pwrseq, return PWRSEQ_MATCH_OK; } +static int pwrseq_qcom_wcn_match(struct pwrseq_device *pwrseq, + struct device *dev) +{ + return pwrseq_qcom_wcn_match_regulator(pwrseq, dev, "vddaon-supply"); +} + +static int pwrseq_qcom_wcn3990_match(struct pwrseq_device *pwrseq, + struct device *dev) +{ + int ret; + + /* BT device */ + ret = pwrseq_qcom_wcn_match_regulator(pwrseq, dev, "vddio-supply"); + if (ret == PWRSEQ_MATCH_OK) + return ret; + + /* WiFi device match */ + return pwrseq_qcom_wcn_match_regulator(pwrseq, dev, "vdd-1.8-xo-supply"); +} + static int pwrseq_qcom_wcn_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -391,6 +485,12 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "Failed to get all regulators\n"); + if (ctx->pdata->has_vddio) { + ctx->vddio = devm_regulator_get(dev, "vddio"); + if (IS_ERR(ctx->vddio)) + return dev_err_probe(dev, ret, "Failed to get VDDIO\n"); + } + ctx->bt_gpio = devm_gpiod_get_optional(dev, "bt-enable", GPIOD_OUT_LOW); if (IS_ERR(ctx->bt_gpio)) return dev_err_probe(dev, PTR_ERR(ctx->bt_gpio), @@ -432,7 +532,7 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev) config.parent = dev; config.owner = THIS_MODULE; config.drvdata = ctx; - config.match = pwrseq_qcom_wcn_match; + config.match = ctx->pdata->match ? : pwrseq_qcom_wcn_match; config.targets = ctx->pdata->targets; ctx->pwrseq = devm_pwrseq_device_register(dev, &config); @@ -444,6 +544,26 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev) } static const struct of_device_id pwrseq_qcom_wcn_of_match[] = { + { + .compatible = "qcom,wcn3950-pmu", + .data = &pwrseq_wcn3990_of_data, + }, + { + .compatible = "qcom,wcn3988-pmu", + .data = &pwrseq_wcn3990_of_data, + }, + { + .compatible = "qcom,wcn3990-pmu", + .data = &pwrseq_wcn3990_of_data, + }, + { + .compatible = "qcom,wcn3991-pmu", + .data = &pwrseq_wcn3990_of_data, + }, + { + .compatible = "qcom,wcn3998-pmu", + .data = &pwrseq_wcn3990_of_data, + }, { .compatible = "qcom,qca6390-pmu", .data = &pwrseq_qca6390_of_data, -- 2.47.3 Follow commit 9c92d36b0b1e ("arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm") and apply the similar fix to the RB2 platform. Having RX / TX pins as pull up and wakup interrupt as high-level triggered generates an interrupt storm when trying to suspend the device. Avoid the storm by using the falling edge trigger (as all other platforms do). Fixes: cab60b166575 ("arm64: dts: qcom: qrb4210-rb2: Enable bluetooth") Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb4210-rb2.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts index 0cd36c54632f..5f8613150bdd 100644 --- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts @@ -694,7 +694,7 @@ sdc2_card_det_n: sd-card-det-n-state { &uart3 { interrupts-extended = <&intc GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, - <&tlmm 11 IRQ_TYPE_LEVEL_HIGH>; + <&tlmm 11 IRQ_TYPE_EDGE_FALLING>; pinctrl-0 = <&uart3_default>; pinctrl-1 = <&uart3_sleep>; pinctrl-names = "default", "sleep"; -- 2.47.3 On SDM845 SPI uses hardware-provided chip select, while specifying cs-gpio makes the driver request GPIO pin, which on DB845c conflicts with the normal host controllers pinctrl entry. Drop the cs-gpios property to restore SPI functionality. Fixes: cb29e7106d4e ("arm64: dts: qcom: db845c: Add support for MCP2517FD") Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index ce23f87e0316..ad283a79bcdb 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -850,7 +850,6 @@ &spi0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&qup_spi0_default>; - cs-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>; can@0 { compatible = "microchip,mcp2517fd"; -- 2.47.3 Specify power supply for the second chain / antenna output of the onboard WiFi chip. Fixes: 3f72e2d3e682 ("arm64: dts: qcom: Add Dragonboard 845c") Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index ad283a79bcdb..5118b776a9bb 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -379,6 +379,12 @@ vreg_l21a_2p95: ldo21 { regulator-initial-mode = ; }; + vreg_l23a_3p3: ldo23 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = ; + }; + vreg_l24a_3p075: ldo24 { regulator-min-microvolt = <3088000>; regulator-max-microvolt = <3088000>; @@ -1155,6 +1161,7 @@ &wifi { vdd-1.8-xo-supply = <&vreg_l7a_1p8>; vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; + vdd-3.3-ch1-supply = <&vreg_l23a_3p3>; qcom,snoc-host-cap-8bit-quirk; qcom,calibration-variant = "Thundercomm_DB845C"; -- 2.47.3 Add UART13, typically used for Bluetooth connection on SM8150. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8150.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index e3ec99972a28..24c1691642c8 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -1693,6 +1693,15 @@ spi13: spi@c8c000 { status = "disabled"; }; + uart13: serial@c8c000 { + compatible = "qcom,geni-uart"; + reg = <0 0x00c8c000 0 0x4000>; + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + interrupts = ; + status = "disabled"; + }; + i2c14: i2c@c90000 { compatible = "qcom,geni-i2c"; reg = <0 0x00c90000 0 0x4000>; -- 2.47.3 The onboard WiFi / BT device, WCN3950, has a simple on-chip PMU, which further spreads generated voltage. Describe the PMU in the device tree. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 60 +++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts index 1b9ca957a94b..4501bc34357b 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts @@ -235,6 +235,42 @@ platform { }; }; }; + + wcn3950-pmu { + compatible = "qcom,wcn3950-pmu"; + + pinctrl-0 = <&sw_ctrl_default>; + pinctrl-names = "default"; + + vddio-supply = <&pm4125_l15>; + vddxo-supply = <&pm4125_l13>; + vddrfa1p3-supply = <&pm4125_l10>; + vddch0-supply = <&pm4125_l22>; + + swctrl-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>; + + regulators { + vreg_pmu_io: ldo0 { + regulator-name = "vreg_pmu_io"; + }; + + vreg_pmu_xo: ldo1 { + regulator-name = "vreg_pmu_xo"; + }; + + vreg_pmu_rf: ldo2 { + regulator-name = "vreg_pmu_rf"; + }; + + vreg_pmu_ch0: ldo3 { + regulator-name = "vreg_pmu_ch0"; + }; + + vreg_pmu_ch1: ldo4 { + regulator-name = "vreg_pmu_ch1"; + }; + }; + }; }; &cpu_pd0 { @@ -679,6 +715,12 @@ lt9611_irq_pin: lt9611-irq-state { bias-disable; }; + sw_ctrl_default: sw-ctrl-default-state { + pins = "gpio87"; + function = "gpio"; + bias-pull-down; + }; + sd_det_in_on: sd-det-in-on-state { pins = "gpio88"; function = "gpio"; @@ -714,11 +756,10 @@ &uart3 { bluetooth { compatible = "qcom,wcn3950-bt"; - vddio-supply = <&pm4125_l15>; - vddxo-supply = <&pm4125_l13>; - vddrf-supply = <&pm4125_l10>; - vddch0-supply = <&pm4125_l22>; - enable-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>; + vddio-supply = <&vreg_pmu_io>; + vddxo-supply = <&vreg_pmu_xo>; + vddrf-supply = <&vreg_pmu_rf>; + vddch0-supply = <&vreg_pmu_ch0>; max-speed = <3200000>; }; }; @@ -759,10 +800,13 @@ &venus { }; &wifi { + /* SoC */ vdd-0.8-cx-mx-supply = <&pm4125_l7>; - vdd-1.8-xo-supply = <&pm4125_l13>; - vdd-1.3-rfa-supply = <&pm4125_l10>; - vdd-3.3-ch0-supply = <&pm4125_l22>; + + /* WiFi / BT PMU */ + vdd-1.8-xo-supply = <&vreg_pmu_xo>; + vdd-1.3-rfa-supply = <&vreg_pmu_rf>; + vdd-3.3-ch0-supply = <&vreg_pmu_ch0>; qcom,calibration-variant = "Thundercomm_RB1"; firmware-name = "qcm2290"; status = "okay"; -- 2.47.3 The onboard WiFi / BT device, WCN3988, has a simple on-chip PMU, which further spreads generated voltage. Describe the PMU in the device tree. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb4210-rb2.dts | 60 +++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts index 5f8613150bdd..4e1b189dc9d7 100644 --- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts @@ -237,6 +237,42 @@ vph_pwr: regulator-vph-pwr { regulator-always-on; regulator-boot-on; }; + + wcn3988-pmu { + compatible = "qcom,wcn3988-pmu"; + + pinctrl-0 = <&sw_ctrl_default>; + pinctrl-names = "default"; + + vddio-supply = <&vreg_l9a_1p8>; + vddxo-supply = <&vreg_l16a_1p3>; + vddrfa1p3-supply = <&vreg_l17a_1p3>; + vddch0-supply = <&vreg_l23a_3p3>; + + swctrl-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>; + + regulators { + vreg_pmu_io: ldo0 { + regulator-name = "vreg_pmu_io"; + }; + + vreg_pmu_xo: ldo1 { + regulator-name = "vreg_pmu_xo"; + }; + + vreg_pmu_rf: ldo2 { + regulator-name = "vreg_pmu_rf"; + }; + + vreg_pmu_ch0: ldo3 { + regulator-name = "vreg_pmu_ch0"; + }; + + vreg_pmu_ch1: ldo4 { + regulator-name = "vreg_pmu_ch1"; + }; + }; + }; }; &gpi_dma0 { @@ -684,6 +720,12 @@ lt9611_irq_pin: lt9611-irq-state { bias-disable; }; + sw_ctrl_default: sw-ctrl-default-state { + pins = "gpio87"; + function = "gpio"; + bias-pull-down; + }; + sdc2_card_det_n: sd-card-det-n-state { pins = "gpio88"; function = "gpio"; @@ -703,11 +745,10 @@ &uart3 { bluetooth { compatible = "qcom,wcn3988-bt"; - vddio-supply = <&vreg_l9a_1p8>; - vddxo-supply = <&vreg_l16a_1p3>; - vddrf-supply = <&vreg_l17a_1p3>; - vddch0-supply = <&vreg_l23a_3p3>; - enable-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>; + vddio-supply = <&vreg_pmu_io>; + vddxo-supply = <&vreg_pmu_xo>; + vddrf-supply = <&vreg_pmu_rf>; + vddch0-supply = <&vreg_pmu_ch0>; max-speed = <3200000>; }; }; @@ -744,10 +785,13 @@ &usb_qmpphy_out { }; &wifi { + /* SoC */ vdd-0.8-cx-mx-supply = <&vreg_l8a_0p664>; - vdd-1.8-xo-supply = <&vreg_l16a_1p3>; - vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; - vdd-3.3-ch0-supply = <&vreg_l23a_3p3>; + + /* WiFi / BT PMU */ + vdd-1.8-xo-supply = <&vreg_pmu_xo>; + vdd-1.3-rfa-supply = <&vreg_pmu_rf>; + vdd-3.3-ch0-supply = <&vreg_pmu_ch0>; qcom,calibration-variant = "Thundercomm_RB2"; firmware-name = "qrb4210"; -- 2.47.3 The onboard WiFi / BT device, WCN3990, has a simple on-chip PMU, which further spreads generated voltage. Describe the PMU in the device tree. Signed-off-by: Dmitry Baryshkov --- .../arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts | 66 +++++++++++++++++++--- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts index 74cb29cb7f1a..b4ea79cbcb3f 100644 --- a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts +++ b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts @@ -108,6 +108,43 @@ vreg_l10a_1p8: vreg-l10a-regulator { regulator-always-on; regulator-boot-on; }; + + wcn3990-pmu { + compatible = "qcom,wcn3990-pmu"; + + pinctrl-0 = <&sw_ctrl_default>; + pinctrl-names = "default"; + + vddio-supply = <&vreg_l13a_1p8>; + vddxo-supply = <&vreg_l9a_1p8>; + vddrfa1p3-supply = <&vreg_l6a_1p3>; + vddch0-supply = <&vreg_l19a_3p3>; + vddch1-supply = <&vreg_l8b_3p3>; + + swctrl-gpios = <&pm660_gpios 5 GPIO_ACTIVE_HIGH>; + + regulators { + vreg_pmu_io: ldo0 { + regulator-name = "vreg_pmu_io"; + }; + + vreg_pmu_xo: ldo1 { + regulator-name = "vreg_pmu_xo"; + }; + + vreg_pmu_rf: ldo2 { + regulator-name = "vreg_pmu_rf"; + }; + + vreg_pmu_ch0: ldo3 { + regulator-name = "vreg_pmu_ch0"; + }; + + vreg_pmu_ch1: ldo4 { + regulator-name = "vreg_pmu_ch1"; + }; + }; + }; }; &adreno_gpu { @@ -197,10 +234,10 @@ &blsp2_uart1 { bluetooth { compatible = "qcom,wcn3990-bt"; - vddio-supply = <&vreg_l13a_1p8>; - vddxo-supply = <&vreg_l9a_1p8>; - vddrf-supply = <&vreg_l6a_1p3>; - vddch0-supply = <&vreg_l19a_3p3>; + vddio-supply = <&vreg_pmu_io>; + vddxo-supply = <&vreg_pmu_xo>; + vddrf-supply = <&vreg_pmu_rf>; + vddch0-supply = <&vreg_pmu_ch0>; max-speed = <3200000>; }; }; @@ -238,6 +275,16 @@ &pon_resin { linux,code = ; }; +&pm660_gpios { + sw_ctrl_default: sw-ctrl-default-state { + pins = "gpio5"; + function = "normal"; + + input-enable; + bias-pull-down; + }; +}; + &qusb2phy0 { status = "okay"; @@ -503,11 +550,14 @@ &usb3_qmpphy { }; &wifi { + /* SoC */ vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>; - vdd-1.8-xo-supply = <&vreg_l9a_1p8>; - vdd-1.3-rfa-supply = <&vreg_l6a_1p3>; - vdd-3.3-ch0-supply = <&vreg_l19a_3p3>; - vdd-3.3-ch1-supply = <&vreg_l8b_3p3>; + + /* WiFi / BT PMU */ + vdd-1.8-xo-supply = <&vreg_pmu_xo>; + vdd-1.3-rfa-supply = <&vreg_pmu_rf>; + vdd-3.3-ch0-supply = <&vreg_pmu_ch0>; + vdd-3.3-ch1-supply = <&vreg_pmu_ch1>; qcom,calibration-variant = "Inforce_IFC6560"; -- 2.47.3 The onboard WiFi / BT device, WCN3990, has a simple on-chip PMU, which further spreads generated voltage. Describe the PMU in the device tree. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 69 +++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index 5118b776a9bb..db221d5c770d 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -276,6 +276,43 @@ vph_pwr: vph-pwr-regulator { vin-supply = <&vbat_som>; }; + + wcn3990-pmu { + compatible = "qcom,wcn3990-pmu"; + + pinctrl-0 = <&sw_ctrl_default>; + pinctrl-names = "default"; + + vddio-supply = <&vreg_s4a_1p8>; + vddxo-supply = <&vreg_l7a_1p8>; + vddrfa1p3-supply = <&vreg_l17a_1p3>; + vddch0-supply = <&vreg_l25a_3p3>; + vddch1-supply = <&vreg_l23a_3p3>; + + swctrl-gpios = <&pm8998_gpios 3 GPIO_ACTIVE_HIGH>; + + regulators { + vreg_pmu_io: ldo0 { + regulator-name = "vreg_pmu_io"; + }; + + vreg_pmu_xo: ldo1 { + regulator-name = "vreg_pmu_xo"; + }; + + vreg_pmu_rf: ldo2 { + regulator-name = "vreg_pmu_rf"; + }; + + vreg_pmu_ch0: ldo3 { + regulator-name = "vreg_pmu_ch0"; + }; + + vreg_pmu_ch1: ldo4 { + regulator-name = "vreg_pmu_ch1"; + }; + }; + }; }; &adsp_pas { @@ -659,6 +696,14 @@ cam0_avdd_2v8_en_default: cam0-avdd-2v8-en-state { qcom,drive-strength = ; }; + sw_ctrl_default: sw-ctrl-default-state { + pins = "gpio3"; + function = "normal"; + + input-enable; + bias-pull-down; + }; + vol_up_pin_a: vol-up-active-state { pins = "gpio6"; function = "normal"; @@ -1038,10 +1083,11 @@ &uart6 { bluetooth { compatible = "qcom,wcn3990-bt"; - vddio-supply = <&vreg_s4a_1p8>; - vddxo-supply = <&vreg_l7a_1p8>; - vddrf-supply = <&vreg_l17a_1p3>; - vddch0-supply = <&vreg_l25a_3p3>; + vddio-supply = <&vreg_pmu_io>; + vddxo-supply = <&vreg_pmu_xo>; + vddrf-supply = <&vreg_pmu_rf>; + vddch0-supply = <&vreg_pmu_ch0>; + max-speed = <3200000>; }; }; @@ -1155,16 +1201,19 @@ right_spkr: speaker@0,2 { }; &wifi { - status = "okay"; - + /* SoC */ vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>; - vdd-1.8-xo-supply = <&vreg_l7a_1p8>; - vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; - vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; - vdd-3.3-ch1-supply = <&vreg_l23a_3p3>; + + /* WiFi / BT PMU */ + vdd-1.8-xo-supply = <&vreg_pmu_xo>; + vdd-1.3-rfa-supply = <&vreg_pmu_rf>; + vdd-3.3-ch0-supply = <&vreg_pmu_ch0>; + vdd-3.3-ch1-supply = <&vreg_pmu_ch1>; qcom,snoc-host-cap-8bit-quirk; qcom,calibration-variant = "Thundercomm_DB845C"; + + status = "okay"; }; /* PINCTRL - additions to nodes defined in sdm845.dtsi */ -- 2.47.3 Properly describe the PMU present as a part of the onboard WCN3998 WiFi/BT chip. Enable Bluetooth part of the chip too. [ 5.479978] Bluetooth: hci0: setting up wcn399x [ 5.633763] Bluetooth: hci0: QCA Product ID :0x0000000a [ 5.645350] Bluetooth: hci0: QCA SOC Version :0x40010224 [ 5.650906] Bluetooth: hci0: QCA ROM Version :0x00001001 [ 5.665173] Bluetooth: hci0: QCA Patch Version:0x00006699 [ 5.679356] Bluetooth: hci0: QCA controller version 0x02241001 [ 5.691109] Bluetooth: hci0: QCA Downloading qca/crbtfw21.tlv [ 6.680102] Bluetooth: hci0: QCA Downloading qca/crnv21.bin [ 6.842948] Bluetooth: hci0: QCA setup on UART is completed [ 81.510709] ath10k_snoc 18800000.wifi: qmi chip_id 0x30224 chip_family 0x4001 board_id 0x55 soc_id 0x40060000 [ 81.521713] ath10k_snoc 18800000.wifi: qmi fw_version 0x32040163 fw_build_timestamp 2019-10-08 05:42 fw_build_id QC_IMAGE_VERSION_STRING=WLAN.HL.3.2.0-00355-QCAHLSWMTPLZ-1 [ 81.554143] ath10k_snoc 18800000.wifi: failed to fetch board data for bus=snoc,qmi-board-id=55,qmi-chip-id=30224,variant=Qualcomm_sm8150hdk from ath10k/WCN3990/hw1.0/board-2.bin [ 85.467464] ath10k_snoc 18800000.wifi: wcn3990 hw1.0 target 0x00000008 chip_id 0x00000000 sub 0000:0000 [ 85.478132] ath10k_snoc 18800000.wifi: kconfig debug 0 debugfs 0 tracing 0 dfs 0 testmode 0 [ 85.487223] ath10k_snoc 18800000.wifi: firmware ver api 5 features wowlan,mgmt-tx-by-reference,non-bmi crc32 b3d4b790 [ 85.758168] ath10k_snoc 18800000.wifi: htt-ver 3.73 wmi-op 4 htt-op 3 cal file max-sta 32 raw 0 hwcrypto 1 [ 85.901630] ath10k_snoc 18800000.wifi: invalid MAC address; choosing random Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8150-hdk.dts | 141 ++++++++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts index 0339a572f34d..18b51a1236de 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts @@ -20,6 +20,7 @@ / { aliases { serial0 = &uart2; + serial1 = &uart13; }; chosen { @@ -66,6 +67,43 @@ hdmi_con: endpoint { }; }; }; + + wcn3998-pmu { + compatible = "qcom,wcn3998-pmu"; + + pinctrl-0 = <&sw_ctrl_default>; + pinctrl-names = "default"; + + vddio-supply = <&vreg_s4a_1p8>; + vddxo-supply = <&vreg_l7a_1p8>; + vddrfa1p3-supply = <&vreg_l2c_1p3>; + vddch0-supply = <&vreg_l11c_3p3>; + vddch1-supply = <&vreg_l10c_3p3>; + + swctrl-gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>; + + regulators { + vreg_pmu_io: ldo0 { + regulator-name = "vreg_pmu_io"; + }; + + vreg_pmu_xo: ldo1 { + regulator-name = "vreg_pmu_xo"; + }; + + vreg_pmu_rf: ldo2 { + regulator-name = "vreg_pmu_rf"; + }; + + vreg_pmu_ch0: ldo3 { + regulator-name = "vreg_pmu_ch0"; + }; + + vreg_pmu_ch1: ldo4 { + regulator-name = "vreg_pmu_ch1"; + }; + }; + }; }; &apps_rsc { @@ -594,6 +632,10 @@ &qupv3_id_1 { status = "okay"; }; +&qupv3_id_2 { + status = "okay"; +}; + &remoteproc_adsp { status = "okay"; @@ -626,12 +668,97 @@ lt9611_irq_pin: lt9611-irq-state { bias-disable; }; + qup_uart13_default: qup-uart13-default-state { + cts-pins { + pins = "gpio43"; + function = "qup13"; + drive-strength = <2>; + bias-bus-hold; + }; + + rts-pins { + pins = "gpio44"; + function = "qup13"; + drive-strength = <2>; + bias-disable; + }; + + tx-pins { + pins = "gpio45"; + function = "qup13"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio46"; + function = "qup13"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + qup_uart13_sleep: qup-uart13-sleep-state { + cts-pins { + pins = "gpio43"; + function = "gpio"; + drive-strength = <2>; + bias-bus-hold; + }; + + rts-pins { + pins = "gpio44"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + tx-pins { + pins = "gpio45"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + rx-pins { + pins = "gpio46"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + sw_ctrl_default: sw-ctrl-default-state { + pins = "gpio50"; + function = "gpio"; + bias-pull-down; + }; }; &uart2 { status = "okay"; }; +&uart13 { + /delete-property/ interrupts; + interrupts-extended = <&intc GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>, + <&tlmm 46 IRQ_TYPE_EDGE_FALLING>; + pinctrl-0 = <&qup_uart13_default>; + pinctrl-1 = <&qup_uart13_sleep>; + pinctrl-names = "default", "sleep"; + + status = "okay"; + + bluetooth { + compatible = "qcom,wcn3998-bt"; + + vddio-supply = <&vreg_pmu_io>; + vddxo-supply = <&vreg_pmu_xo>; + vddrf-supply = <&vreg_pmu_rf>; + vddch0-supply = <&vreg_pmu_ch0>; + }; +}; + &ufs_mem_hc { status = "okay"; @@ -705,12 +832,16 @@ &usb_2_dwc3 { }; &wifi { - status = "okay"; - + /* SoC */ vdd-0.8-cx-mx-supply = <&vreg_l1a_0p75>; - vdd-1.8-xo-supply = <&vreg_l7a_1p8>; - vdd-1.3-rfa-supply = <&vreg_l2c_1p3>; - vdd-3.3-ch0-supply = <&vreg_l11c_3p3>; + + /* WiFi / BT PMU */ + vdd-1.8-xo-supply = <&vreg_pmu_xo>; + vdd-1.3-rfa-supply = <&vreg_pmu_rf>; + vdd-3.3-ch0-supply = <&vreg_pmu_ch0>; + vdd-3.3-ch1-supply = <&vreg_pmu_ch1>; qcom,calibration-variant = "Qualcomm_sm8150hdk"; + + status = "okay"; }; -- 2.47.3