aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2017-07-03 09:00:31 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-07-03 09:00:31 -0400
commit6f65daed5bcca6d4e419c0b914f392c7fdb48027 (patch)
tree51273b90d1dfbeaa2230a4e5d0f85936458182a4
parentecf75c46e6a43eb083c9dfbbe7903ec81dcd524a (diff)
parent2eeb02b28579fc317504a691f3acb0b9bf94b42b (diff)
Merge branch 'pci/host-faraday' into next
* pci/host-faraday: PCI: faraday: Add clock handling PCI: faraday: Add clock bindings
-rw-r--r--Documentation/devicetree/bindings/pci/faraday,ftpci100.txt7
-rw-r--r--drivers/pci/host/pci-ftpci100.c56
2 files changed, 63 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/pci/faraday,ftpci100.txt b/Documentation/devicetree/bindings/pci/faraday,ftpci100.txt
index 35d4a979bb7b..89a84f8aa621 100644
--- a/Documentation/devicetree/bindings/pci/faraday,ftpci100.txt
+++ b/Documentation/devicetree/bindings/pci/faraday,ftpci100.txt
@@ -30,6 +30,13 @@ Mandatory properties:
30 128MB, 256MB, 512MB, 1GB or 2GB in size. The memory should be marked as 30 128MB, 256MB, 512MB, 1GB or 2GB in size. The memory should be marked as
31 pre-fetchable. 31 pre-fetchable.
32 32
33Optional properties:
34- clocks: when present, this should contain the peripheral clock (PCLK) and the
35 PCI clock (PCICLK). If these are not present, they are assumed to be
36 hard-wired enabled and always on. The PCI clock will be 33 or 66 MHz.
37- clock-names: when present, this should contain "PCLK" for the peripheral
38 clock and "PCICLK" for the PCI-side clock.
39
33Mandatory subnodes: 40Mandatory subnodes:
34- For "faraday,ftpci100" a node representing the interrupt-controller inside the 41- For "faraday,ftpci100" a node representing the interrupt-controller inside the
35 host bridge is mandatory. It has the following mandatory properties: 42 host bridge is mandatory. It has the following mandatory properties:
diff --git a/drivers/pci/host/pci-ftpci100.c b/drivers/pci/host/pci-ftpci100.c
index e938eebcb180..5162dffc102b 100644
--- a/drivers/pci/host/pci-ftpci100.c
+++ b/drivers/pci/host/pci-ftpci100.c
@@ -25,6 +25,7 @@
25#include <linux/irqchip/chained_irq.h> 25#include <linux/irqchip/chained_irq.h>
26#include <linux/bitops.h> 26#include <linux/bitops.h>
27#include <linux/irq.h> 27#include <linux/irq.h>
28#include <linux/clk.h>
28 29
29/* 30/*
30 * Special configuration registers directly in the first few words 31 * Special configuration registers directly in the first few words
@@ -37,6 +38,7 @@
37#define PCI_CONFIG 0x28 /* PCI configuration command register */ 38#define PCI_CONFIG 0x28 /* PCI configuration command register */
38#define PCI_DATA 0x2C 39#define PCI_DATA 0x2C
39 40
41#define FARADAY_PCI_STATUS_CMD 0x04 /* Status and command */
40#define FARADAY_PCI_PMC 0x40 /* Power management control */ 42#define FARADAY_PCI_PMC 0x40 /* Power management control */
41#define FARADAY_PCI_PMCSR 0x44 /* Power management status */ 43#define FARADAY_PCI_PMCSR 0x44 /* Power management status */
42#define FARADAY_PCI_CTRL1 0x48 /* Control register 1 */ 44#define FARADAY_PCI_CTRL1 0x48 /* Control register 1 */
@@ -45,6 +47,8 @@
45#define FARADAY_PCI_MEM2_BASE_SIZE 0x54 /* Memory base and size #2 */ 47#define FARADAY_PCI_MEM2_BASE_SIZE 0x54 /* Memory base and size #2 */
46#define FARADAY_PCI_MEM3_BASE_SIZE 0x58 /* Memory base and size #3 */ 48#define FARADAY_PCI_MEM3_BASE_SIZE 0x58 /* Memory base and size #3 */
47 49
50#define PCI_STATUS_66MHZ_CAPABLE BIT(21)
51
48/* Bits 31..28 gives INTD..INTA status */ 52/* Bits 31..28 gives INTD..INTA status */
49#define PCI_CTRL2_INTSTS_SHIFT 28 53#define PCI_CTRL2_INTSTS_SHIFT 28
50#define PCI_CTRL2_INTMASK_CMDERR BIT(27) 54#define PCI_CTRL2_INTMASK_CMDERR BIT(27)
@@ -117,6 +121,7 @@ struct faraday_pci {
117 void __iomem *base; 121 void __iomem *base;
118 struct irq_domain *irqdomain; 122 struct irq_domain *irqdomain;
119 struct pci_bus *bus; 123 struct pci_bus *bus;
124 struct clk *bus_clk;
120}; 125};
121 126
122static int faraday_res_to_memcfg(resource_size_t mem_base, 127static int faraday_res_to_memcfg(resource_size_t mem_base,
@@ -444,6 +449,9 @@ static int faraday_pci_probe(struct platform_device *pdev)
444 struct resource *mem; 449 struct resource *mem;
445 struct resource *io; 450 struct resource *io;
446 struct pci_host_bridge *host; 451 struct pci_host_bridge *host;
452 struct clk *clk;
453 unsigned char max_bus_speed = PCI_SPEED_33MHz;
454 unsigned char cur_bus_speed = PCI_SPEED_33MHz;
447 int ret; 455 int ret;
448 u32 val; 456 u32 val;
449 LIST_HEAD(res); 457 LIST_HEAD(res);
@@ -462,6 +470,24 @@ static int faraday_pci_probe(struct platform_device *pdev)
462 host->sysdata = p; 470 host->sysdata = p;
463 p->dev = dev; 471 p->dev = dev;
464 472
473 /* Retrieve and enable optional clocks */
474 clk = devm_clk_get(dev, "PCLK");
475 if (IS_ERR(clk))
476 return PTR_ERR(clk);
477 ret = clk_prepare_enable(clk);
478 if (ret) {
479 dev_err(dev, "could not prepare PCLK\n");
480 return ret;
481 }
482 p->bus_clk = devm_clk_get(dev, "PCICLK");
483 if (IS_ERR(p->bus_clk))
484 return PTR_ERR(clk);
485 ret = clk_prepare_enable(p->bus_clk);
486 if (ret) {
487 dev_err(dev, "could not prepare PCICLK\n");
488 return ret;
489 }
490
465 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 491 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
466 p->base = devm_ioremap_resource(dev, regs); 492 p->base = devm_ioremap_resource(dev, regs);
467 if (IS_ERR(p->base)) 493 if (IS_ERR(p->base))
@@ -524,6 +550,34 @@ static int faraday_pci_probe(struct platform_device *pdev)
524 } 550 }
525 } 551 }
526 552
553 /* Check bus clock if we can gear up to 66 MHz */
554 if (!IS_ERR(p->bus_clk)) {
555 unsigned long rate;
556 u32 val;
557
558 faraday_raw_pci_read_config(p, 0, 0,
559 FARADAY_PCI_STATUS_CMD, 4, &val);
560 rate = clk_get_rate(p->bus_clk);
561
562 if ((rate == 33000000) && (val & PCI_STATUS_66MHZ_CAPABLE)) {
563 dev_info(dev, "33MHz bus is 66MHz capable\n");
564 max_bus_speed = PCI_SPEED_66MHz;
565 ret = clk_set_rate(p->bus_clk, 66000000);
566 if (ret)
567 dev_err(dev, "failed to set bus clock\n");
568 } else {
569 dev_info(dev, "33MHz only bus\n");
570 max_bus_speed = PCI_SPEED_33MHz;
571 }
572
573 /* Bumping the clock may fail so read back the rate */
574 rate = clk_get_rate(p->bus_clk);
575 if (rate == 33000000)
576 cur_bus_speed = PCI_SPEED_33MHz;
577 if (rate == 66000000)
578 cur_bus_speed = PCI_SPEED_66MHz;
579 }
580
527 ret = faraday_pci_parse_map_dma_ranges(p, dev->of_node); 581 ret = faraday_pci_parse_map_dma_ranges(p, dev->of_node);
528 if (ret) 582 if (ret)
529 return ret; 583 return ret;
@@ -535,6 +589,8 @@ static int faraday_pci_probe(struct platform_device *pdev)
535 return ret; 589 return ret;
536 } 590 }
537 p->bus = host->bus; 591 p->bus = host->bus;
592 p->bus->max_bus_speed = max_bus_speed;
593 p->bus->cur_bus_speed = cur_bus_speed;
538 594
539 pci_bus_assign_resources(p->bus); 595 pci_bus_assign_resources(p->bus);
540 pci_bus_add_devices(p->bus); 596 pci_bus_add_devices(p->bus);