aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKishon Vijay Abraham I2017-08-24 09:12:49 -0500
committerJean-Jacques Hiblot2017-08-25 07:16:12 -0500
commit33496ede38c37090e3fdcb8075bd93ac423c6063 (patch)
treeb5bd38185fa3b692b53421007dffdbe5419712f9
parent64fe08d902ef914346be6309bd4c317d56b191b9 (diff)
downloadkernel-omap-33496ede38c37090e3fdcb8075bd93ac423c6063.tar.gz
kernel-omap-33496ede38c37090e3fdcb8075bd93ac423c6063.tar.xz
kernel-omap-33496ede38c37090e3fdcb8075bd93ac423c6063.zip
PCI: dwc: pci-dra7xx: Enable x2 mode support
Perform syscon configurations to get x2 mode to working in dra74x (and dra76x). Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
-rw-r--r--drivers/pci/controller/pci-dra7xx.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/drivers/pci/controller/pci-dra7xx.c b/drivers/pci/controller/pci-dra7xx.c
index 88a649267213..330866f9b924 100644
--- a/drivers/pci/controller/pci-dra7xx.c
+++ b/drivers/pci/controller/pci-dra7xx.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/of_gpio.h> 20#include <linux/of_gpio.h>
21#include <linux/of_device.h> 21#include <linux/of_device.h>
22#include <linux/of_platform.h>
22#include <linux/pci.h> 23#include <linux/pci.h>
23#include <linux/phy/phy.h> 24#include <linux/phy/phy.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
@@ -81,6 +82,9 @@
81#define MSI_REQ_GRANT BIT(0) 82#define MSI_REQ_GRANT BIT(0)
82#define MSI_VECTOR_SHIFT 7 83#define MSI_VECTOR_SHIFT 7
83 84
85#define PCIE_1LANE_2LANE_SELECTION BIT(13)
86#define PCIE_B1C0_MODE_SEL BIT(2)
87
84struct dra7xx_pcie { 88struct dra7xx_pcie {
85 void __iomem *base; 89 void __iomem *base;
86 struct phy **phy; 90 struct phy **phy;
@@ -94,6 +98,10 @@ struct dra7xx_pcie {
94 98
95struct dra7xx_pcie_of_data { 99struct dra7xx_pcie_of_data {
96 enum dw_pcie_device_mode mode; 100 enum dw_pcie_device_mode mode;
101 u32 b1co_mode_sel_mask;
102};
103
104struct dra7xx_pcie_data {
97}; 105};
98 106
99#define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev) 107#define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev)
@@ -506,6 +514,16 @@ static const struct dra7xx_pcie_of_data dra7xx_pcie_ep_of_data = {
506 .mode = DW_PCIE_EP_TYPE, 514 .mode = DW_PCIE_EP_TYPE,
507}; 515};
508 516
517static const struct dra7xx_pcie_of_data dra746_pcie_rc_of_data = {
518 .b1co_mode_sel_mask = BIT(2),
519 .mode = DW_PCIE_RC_TYPE,
520};
521
522static const struct dra7xx_pcie_of_data dra746_pcie_ep_of_data = {
523 .b1co_mode_sel_mask = BIT(2),
524 .mode = DW_PCIE_EP_TYPE,
525};
526
509static const struct of_device_id of_dra7xx_pcie_match[] = { 527static const struct of_device_id of_dra7xx_pcie_match[] = {
510 { 528 {
511 .compatible = "ti,dra7-pcie", 529 .compatible = "ti,dra7-pcie",
@@ -517,11 +535,11 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
517 }, 535 },
518 { 536 {
519 .compatible = "ti,dra746-pcie-rc", 537 .compatible = "ti,dra746-pcie-rc",
520 .data = &dra7xx_pcie_rc_of_data, 538 .data = &dra746_pcie_rc_of_data,
521 }, 539 },
522 { 540 {
523 .compatible = "ti,dra746-pcie-ep", 541 .compatible = "ti,dra746-pcie-ep",
524 .data = &dra7xx_pcie_ep_of_data, 542 .data = &dra746_pcie_ep_of_data,
525 }, 543 },
526 { 544 {
527 .compatible = "ti,dra726-pcie-rc", 545 .compatible = "ti,dra726-pcie-rc",
@@ -578,6 +596,44 @@ static int dra7xx_pcie_ep_legacy_mode(struct dra7xx_pcie *dra7xx)
578 return ret; 596 return ret;
579} 597}
580 598
599static int dra7xx_pcie_configure_two_lane(struct device *dev,
600 u32 b1co_mode_sel_mask)
601{
602 struct device_node *np = dev->of_node;
603 struct regmap *pcie_syscon;
604 unsigned int pcie_reg;
605
606 pcie_syscon = syscon_regmap_lookup_by_phandle(np, "syscon-lane-conf");
607 if (IS_ERR(pcie_syscon)) {
608 dev_err(dev, "unable to get syscon-lane-conf\n");
609 return -EINVAL;
610 }
611
612 if (of_property_read_u32_index(np, "syscon-lane-conf", 1, &pcie_reg)) {
613 dev_err(dev, "couldn't get lane configuration reg offset\n");
614 return -EINVAL;
615 }
616
617 regmap_update_bits(pcie_syscon, pcie_reg, PCIE_1LANE_2LANE_SELECTION,
618 PCIE_1LANE_2LANE_SELECTION);
619
620 pcie_syscon = syscon_regmap_lookup_by_phandle(np, "syscon-lane-sel");
621 if (IS_ERR(pcie_syscon)) {
622 dev_err(dev, "unable to get syscon-lane-sel\n");
623 return -EINVAL;
624 }
625
626 if (of_property_read_u32_index(np, "syscon-lane-sel", 1, &pcie_reg)) {
627 dev_err(dev, "couldn't get lane selection reg offset\n");
628 return -EINVAL;
629 }
630
631 regmap_update_bits(pcie_syscon, pcie_reg, b1co_mode_sel_mask,
632 PCIE_B1C0_MODE_SEL);
633
634 return 0;
635}
636
581static int __init dra7xx_pcie_probe(struct platform_device *pdev) 637static int __init dra7xx_pcie_probe(struct platform_device *pdev)
582{ 638{
583 u32 reg; 639 u32 reg;
@@ -597,6 +653,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
597 const struct of_device_id *match; 653 const struct of_device_id *match;
598 const struct dra7xx_pcie_of_data *data; 654 const struct dra7xx_pcie_of_data *data;
599 enum dw_pcie_device_mode mode; 655 enum dw_pcie_device_mode mode;
656 u32 b1co_mode_sel_mask;
600 657
601 match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev); 658 match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev);
602 if (!match) 659 if (!match)
@@ -604,6 +661,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
604 661
605 data = (struct dra7xx_pcie_of_data *)match->data; 662 data = (struct dra7xx_pcie_of_data *)match->data;
606 mode = (enum dw_pcie_device_mode)data->mode; 663 mode = (enum dw_pcie_device_mode)data->mode;
664 b1co_mode_sel_mask = data->b1co_mode_sel_mask;
607 665
608 dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); 666 dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
609 if (!dra7xx) 667 if (!dra7xx)
@@ -667,6 +725,12 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
667 dra7xx->dev = dev; 725 dra7xx->dev = dev;
668 dra7xx->phy_count = phy_count; 726 dra7xx->phy_count = phy_count;
669 727
728 if (phy_count == 2) {
729 ret = dra7xx_pcie_configure_two_lane(dev, b1co_mode_sel_mask);
730 if (ret < 0)
731 goto err_phy;
732 }
733
670 pm_runtime_enable(dev); 734 pm_runtime_enable(dev);
671 ret = pm_runtime_get_sync(dev); 735 ret = pm_runtime_get_sync(dev);
672 if (ret < 0) { 736 if (ret < 0) {