Commit c232c0df authored by Kishon Vijay Abraham I's avatar Kishon Vijay Abraham I Committed by Lorenzo Pieralisi

PCI: dwc: dra7xx: Enable x2 mode support for dra74x, dra76x and dra72x

dra74x/dra76x and dra72x have separate compatible strings. Add support
for these compatible strings in pci-dra7xx driver to perform syscon
configurations required to get x2 mode working.
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
parent 1c5d2cc7
...@@ -81,6 +81,10 @@ ...@@ -81,6 +81,10 @@
#define MSI_REQ_GRANT BIT(0) #define MSI_REQ_GRANT BIT(0)
#define MSI_VECTOR_SHIFT 7 #define MSI_VECTOR_SHIFT 7
#define PCIE_1LANE_2LANE_SELECTION BIT(13)
#define PCIE_B1C0_MODE_SEL BIT(2)
#define PCIE_B0_B1_TSYNCEN BIT(0)
struct dra7xx_pcie { struct dra7xx_pcie {
struct dw_pcie *pci; struct dw_pcie *pci;
void __iomem *base; /* DT ti_conf */ void __iomem *base; /* DT ti_conf */
...@@ -93,6 +97,7 @@ struct dra7xx_pcie { ...@@ -93,6 +97,7 @@ struct dra7xx_pcie {
struct dra7xx_pcie_of_data { struct dra7xx_pcie_of_data {
enum dw_pcie_device_mode mode; enum dw_pcie_device_mode mode;
u32 b1co_mode_sel_mask;
}; };
#define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev) #define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev)
...@@ -529,6 +534,26 @@ static const struct dra7xx_pcie_of_data dra7xx_pcie_ep_of_data = { ...@@ -529,6 +534,26 @@ static const struct dra7xx_pcie_of_data dra7xx_pcie_ep_of_data = {
.mode = DW_PCIE_EP_TYPE, .mode = DW_PCIE_EP_TYPE,
}; };
static const struct dra7xx_pcie_of_data dra746_pcie_rc_of_data = {
.b1co_mode_sel_mask = BIT(2),
.mode = DW_PCIE_RC_TYPE,
};
static const struct dra7xx_pcie_of_data dra726_pcie_rc_of_data = {
.b1co_mode_sel_mask = GENMASK(3, 2),
.mode = DW_PCIE_RC_TYPE,
};
static const struct dra7xx_pcie_of_data dra746_pcie_ep_of_data = {
.b1co_mode_sel_mask = BIT(2),
.mode = DW_PCIE_EP_TYPE,
};
static const struct dra7xx_pcie_of_data dra726_pcie_ep_of_data = {
.b1co_mode_sel_mask = GENMASK(3, 2),
.mode = DW_PCIE_EP_TYPE,
};
static const struct of_device_id of_dra7xx_pcie_match[] = { static const struct of_device_id of_dra7xx_pcie_match[] = {
{ {
.compatible = "ti,dra7-pcie", .compatible = "ti,dra7-pcie",
...@@ -538,6 +563,22 @@ static const struct of_device_id of_dra7xx_pcie_match[] = { ...@@ -538,6 +563,22 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
.compatible = "ti,dra7-pcie-ep", .compatible = "ti,dra7-pcie-ep",
.data = &dra7xx_pcie_ep_of_data, .data = &dra7xx_pcie_ep_of_data,
}, },
{
.compatible = "ti,dra746-pcie-rc",
.data = &dra746_pcie_rc_of_data,
},
{
.compatible = "ti,dra726-pcie-rc",
.data = &dra726_pcie_rc_of_data,
},
{
.compatible = "ti,dra746-pcie-ep",
.data = &dra746_pcie_ep_of_data,
},
{
.compatible = "ti,dra726-pcie-ep",
.data = &dra726_pcie_ep_of_data,
},
{}, {},
}; };
...@@ -583,6 +624,34 @@ static int dra7xx_pcie_unaligned_memaccess(struct device *dev) ...@@ -583,6 +624,34 @@ static int dra7xx_pcie_unaligned_memaccess(struct device *dev)
return ret; return ret;
} }
static int dra7xx_pcie_configure_two_lane(struct device *dev,
u32 b1co_mode_sel_mask)
{
struct device_node *np = dev->of_node;
struct regmap *pcie_syscon;
unsigned int pcie_reg;
u32 mask;
u32 val;
pcie_syscon = syscon_regmap_lookup_by_phandle(np, "ti,syscon-lane-sel");
if (IS_ERR(pcie_syscon)) {
dev_err(dev, "unable to get ti,syscon-lane-sel\n");
return -EINVAL;
}
if (of_property_read_u32_index(np, "ti,syscon-lane-sel", 1,
&pcie_reg)) {
dev_err(dev, "couldn't get lane selection reg offset\n");
return -EINVAL;
}
mask = b1co_mode_sel_mask | PCIE_B0_B1_TSYNCEN;
val = PCIE_B1C0_MODE_SEL | PCIE_B0_B1_TSYNCEN;
regmap_update_bits(pcie_syscon, pcie_reg, mask, val);
return 0;
}
static int __init dra7xx_pcie_probe(struct platform_device *pdev) static int __init dra7xx_pcie_probe(struct platform_device *pdev)
{ {
u32 reg; u32 reg;
...@@ -603,6 +672,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) ...@@ -603,6 +672,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
const struct of_device_id *match; const struct of_device_id *match;
const struct dra7xx_pcie_of_data *data; const struct dra7xx_pcie_of_data *data;
enum dw_pcie_device_mode mode; enum dw_pcie_device_mode mode;
u32 b1co_mode_sel_mask;
match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev); match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev);
if (!match) if (!match)
...@@ -610,6 +680,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) ...@@ -610,6 +680,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
data = (struct dra7xx_pcie_of_data *)match->data; data = (struct dra7xx_pcie_of_data *)match->data;
mode = (enum dw_pcie_device_mode)data->mode; mode = (enum dw_pcie_device_mode)data->mode;
b1co_mode_sel_mask = data->b1co_mode_sel_mask;
dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
if (!dra7xx) if (!dra7xx)
...@@ -665,6 +736,12 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) ...@@ -665,6 +736,12 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
dra7xx->pci = pci; dra7xx->pci = pci;
dra7xx->phy_count = phy_count; dra7xx->phy_count = phy_count;
if (phy_count == 2) {
ret = dra7xx_pcie_configure_two_lane(dev, b1co_mode_sel_mask);
if (ret < 0)
dra7xx->phy_count = 1; /* Fallback to x1 lane mode */
}
ret = dra7xx_pcie_enable_phy(dra7xx); ret = dra7xx_pcie_enable_phy(dra7xx);
if (ret) { if (ret) {
dev_err(dev, "failed to enable phy\n"); dev_err(dev, "failed to enable phy\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment