diff mbox series

[v2,3/5] pcie-qcom: provide a way to power up qca6390 chip on RB5 platform

Message ID 20210128175225.3102958-4-dmitry.baryshkov@linaro.org
State New
Headers show
Series Add support for Qualcomm QCA639x chips family | expand

Commit Message

Dmitry Baryshkov Jan. 28, 2021, 5:52 p.m. UTC
Some Qualcomm platforms require to power up an external device before
probing the PCI bus. E.g. on RB5 platform the QCA6390 WiFi/BT chip needs
to be powered up before PCIe0 bus is probed. Add a quirk to the
respective PCIe root bridge to attach to the power domain if one is
required, so that the QCA chip is started before scanning the PCIe bus.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/pci/controller/dwc/pcie-qcom.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

Comments

Dmitry Baryshkov Jan. 29, 2021, 3:45 a.m. UTC | #1
On 28/01/2021 22:26, Rob Herring wrote:
> On Thu, Jan 28, 2021 at 11:52 AM Dmitry Baryshkov
> <dmitry.baryshkov@linaro.org> wrote:
>>
>> Some Qualcomm platforms require to power up an external device before
>> probing the PCI bus. E.g. on RB5 platform the QCA6390 WiFi/BT chip needs
>> to be powered up before PCIe0 bus is probed. Add a quirk to the
>> respective PCIe root bridge to attach to the power domain if one is
>> required, so that the QCA chip is started before scanning the PCIe bus.
> 
> This is solving a generic problem in a specific driver. It needs to be
> solved for any PCI host and any device.

Ack. I see your point here.

As this would require porting code from powerpc/spark of-pci code and 
changing pcie port driver to apply power supply before bus probing 
happens, I'd also ask for the comments from PCI maintainers. Will that 
solution be acceptable to you?


> 
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/pci/controller/dwc/pcie-qcom.c | 21 +++++++++++++++++++++
>>   1 file changed, 21 insertions(+)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index ab21aa01c95d..eb73c8540d4d 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -20,6 +20,7 @@
>>   #include <linux/of_device.h>
>>   #include <linux/of_gpio.h>
>>   #include <linux/pci.h>
>> +#include <linux/pm_domain.h>
>>   #include <linux/pm_runtime.h>
>>   #include <linux/platform_device.h>
>>   #include <linux/phy/phy.h>
>> @@ -1568,6 +1569,26 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0302, qcom_fixup_class);
>>   DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1000, qcom_fixup_class);
>>   DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1001, qcom_fixup_class);
>>
>> +static void qcom_fixup_power(struct pci_dev *dev)
>> +{
>> +       int ret;
>> +       struct pcie_port *pp = dev->bus->sysdata;
>> +       struct dw_pcie *pci;
>> +
>> +       if (!pci_is_root_bus(dev->bus))
>> +               return;
>> +
>> +       ret = dev_pm_domain_attach(&dev->dev, true);
>> +       if (ret < 0 || !dev->dev.pm_domain)
>> +               return;
>> +
>> +       pci = to_dw_pcie_from_pp(pp);
>> +       dev_info(&dev->dev, "Bus powered up, waiting for link to come up\n");
>> +
>> +       dw_pcie_wait_for_link(pci);
>> +}
>> +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x010b, qcom_fixup_power);
>> +
>>   static struct platform_driver qcom_pcie_driver = {
>>          .probe = qcom_pcie_probe,
>>          .driver = {
>> --
>> 2.29.2
>>
Konrad Dybcio June 13, 2021, 6:40 p.m. UTC | #2
Hi, bumping the discussion as solving this is crucial for Wi-Fi and Bluetooth to work on a good number (which will probably increase with time) of Qualcomm devices, including newer phones.


Konrad
diff mbox series

Patch

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index ab21aa01c95d..eb73c8540d4d 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -20,6 +20,7 @@ 
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
 #include <linux/pci.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/platform_device.h>
 #include <linux/phy/phy.h>
@@ -1568,6 +1569,26 @@  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0302, qcom_fixup_class);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1000, qcom_fixup_class);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1001, qcom_fixup_class);
 
+static void qcom_fixup_power(struct pci_dev *dev)
+{
+	int ret;
+	struct pcie_port *pp = dev->bus->sysdata;
+	struct dw_pcie *pci;
+
+	if (!pci_is_root_bus(dev->bus))
+		return;
+
+	ret = dev_pm_domain_attach(&dev->dev, true);
+	if (ret < 0 || !dev->dev.pm_domain)
+		return;
+
+	pci = to_dw_pcie_from_pp(pp);
+	dev_info(&dev->dev, "Bus powered up, waiting for link to come up\n");
+
+	dw_pcie_wait_for_link(pci);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x010b, qcom_fixup_power);
+
 static struct platform_driver qcom_pcie_driver = {
 	.probe = qcom_pcie_probe,
 	.driver = {