Commit c0d12ce9fd7dbec07ec5f26f2ef830b9c385356f

Authored by Richard Zhu
1 parent 6adee22e7f

MLK-10017 PCI: save power when pcie is not used

In order to save power consumption, do the
following actions when pcie is not used.
- turn off clocks on imx6q/dl.
- turn off clocks and power on imx6sx

Signed-off-by: Richard Zhu <Richard.Zhu@freescale.com>
(cherry picked from commit e9796dfbae2a8b732022a6c96b3d7803099a70b5)

Showing 3 changed files with 33 additions and 7 deletions Side-by-side Diff

drivers/pci/host/pci-imx6.c
... ... @@ -422,7 +422,7 @@
422 422 return IRQ_HANDLED;
423 423 }
424 424  
425   -static void imx6_pcie_host_init(struct pcie_port *pp)
  425 +static int imx6_pcie_host_init(struct pcie_port *pp)
426 426 {
427 427 int count = 0;
428 428 struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
429 429  
... ... @@ -459,14 +459,37 @@
459 459 "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
460 460 readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
461 461 readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
462   - return;
  462 + clk_disable_unprepare(imx6_pcie->pcie_axi);
  463 + if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
  464 + && !IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS))
  465 + clk_disable_unprepare(imx6_pcie->lvds_gate);
  466 + clk_disable_unprepare(imx6_pcie->pcie_ref_125m);
  467 + if (is_imx6sx_pcie(imx6_pcie)) {
  468 + /* Disable clks and power down PCIe PHY */
  469 + clk_disable_unprepare(imx6_pcie->dis_axi);
  470 + release_bus_freq(BUS_FREQ_HIGH);
  471 +
  472 + /* Put PCIe PHY to be isolation */
  473 + regmap_update_bits(imx6_pcie->iomuxc_gpr,
  474 + IOMUXC_GPR0, BIT(6), 1 << 6);
  475 +
  476 + /*
  477 + * Power down PCIe PHY.
  478 + */
  479 + regulator_disable(imx6_pcie->pcie_phy_reg);
  480 + regulator_disable(imx6_pcie->pcie_reg);
  481 + } else {
  482 + clk_disable_unprepare(imx6_pcie->sata_ref_100m);
  483 + release_bus_freq(BUS_FREQ_HIGH);
  484 + }
  485 + return -ENODEV;
463 486 }
464 487 }
465 488  
466 489 if (IS_ENABLED(CONFIG_PCI_MSI))
467 490 dw_pcie_msi_init(pp);
468 491  
469   - return;
  492 + return 0;
470 493 }
471 494  
472 495 static int imx6_pcie_link_up(struct pcie_port *pp)
drivers/pci/host/pcie-designware.c
... ... @@ -408,7 +408,7 @@
408 408 struct of_pci_range range;
409 409 struct of_pci_range_parser parser;
410 410 u32 val;
411   - int i;
  411 + int i, ret = 0;
412 412  
413 413 if (of_pci_range_parser_init(&parser, np)) {
414 414 dev_err(pp->dev, "missing ranges property\n");
... ... @@ -489,8 +489,11 @@
489 489 irq_create_mapping(pp->irq_domain, i);
490 490 }
491 491  
492   - if (pp->ops->host_init)
493   - pp->ops->host_init(pp);
  492 + if (pp->ops->host_init) {
  493 + ret = pp->ops->host_init(pp);
  494 + if (ret < 0)
  495 + return -ENODEV;
  496 + }
494 497  
495 498 dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
496 499  
drivers/pci/host/pcie-designware.h
... ... @@ -107,7 +107,7 @@
107 107 int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
108 108 int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val);
109 109 int (*link_up)(struct pcie_port *pp);
110   - void (*host_init)(struct pcie_port *pp);
  110 + int (*host_init)(struct pcie_port *pp);
111 111 void (*msi_set_irq)(struct pcie_port *pp, int irq);
112 112 void (*msi_clear_irq)(struct pcie_port *pp, int irq);
113 113 u32 (*get_msi_data)(struct pcie_port *pp);