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: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
This commit is contained in:
parent
1c5d2cc719
commit
c232c0df96
|
@ -81,6 +81,10 @@
|
|||
#define MSI_REQ_GRANT BIT(0)
|
||||
#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 dw_pcie *pci;
|
||||
void __iomem *base; /* DT ti_conf */
|
||||
|
@ -93,6 +97,7 @@ struct dra7xx_pcie {
|
|||
|
||||
struct dra7xx_pcie_of_data {
|
||||
enum dw_pcie_device_mode mode;
|
||||
u32 b1co_mode_sel_mask;
|
||||
};
|
||||
|
||||
#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 = {
|
|||
.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[] = {
|
||||
{
|
||||
.compatible = "ti,dra7-pcie",
|
||||
|
@ -538,6 +563,22 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
|
|||
.compatible = "ti,dra7-pcie-ep",
|
||||
.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)
|
|||
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)
|
||||
{
|
||||
u32 reg;
|
||||
|
@ -603,6 +672,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
|
|||
const struct of_device_id *match;
|
||||
const struct dra7xx_pcie_of_data *data;
|
||||
enum dw_pcie_device_mode mode;
|
||||
u32 b1co_mode_sel_mask;
|
||||
|
||||
match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev);
|
||||
if (!match)
|
||||
|
@ -610,6 +680,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
|
|||
|
||||
data = (struct dra7xx_pcie_of_data *)match->data;
|
||||
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);
|
||||
if (!dra7xx)
|
||||
|
@ -665,6 +736,12 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
|
|||
dra7xx->pci = pci;
|
||||
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);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable phy\n");
|
||||
|
|
Loading…
Reference in New Issue