Message ID | 20210706105035.9915-3-kishon@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | PCI: Add support for J7200 and AM64 | expand |
On Tue, Jul 06, 2021 at 04:20:32PM +0530, Kishon Vijay Abraham I wrote: > J7200 has the same PCIe IP as in J721E with minor changes in the > wrapper. J7200 allows byte access of bridge configuration space > registers and the register field for LINK_DOWN interrupt is different. > J7200 also requires "quirk_detect_quiet_flag" to be set. Configure these > changes as part of driver data applicable only to J7200. > > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> > --- > drivers/pci/controller/cadence/pci-j721e.c | 44 ++++++++++++++++++++-- > 1 file changed, 40 insertions(+), 4 deletions(-) > > diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c > index 35e61048e133..803da33b86d8 100644 > --- a/drivers/pci/controller/cadence/pci-j721e.c > +++ b/drivers/pci/controller/cadence/pci-j721e.c > @@ -27,6 +27,7 @@ > #define STATUS_REG_SYS_2 0x508 > #define STATUS_CLR_REG_SYS_2 0x708 > #define LINK_DOWN BIT(1) > +#define J7200_LINK_DOWN BIT(10) > > #define J721E_PCIE_USER_CMD_STATUS 0x4 > #define LINK_TRAINING_ENABLE BIT(0) > @@ -57,6 +58,7 @@ struct j721e_pcie { > struct cdns_pcie *cdns_pcie; > void __iomem *user_cfg_base; > void __iomem *intd_cfg_base; > + u32 link_irq_reg_field; This seems to be a device-specific "link down" bit, so maybe a more descriptive name that suggests "link down"? > }; > > enum j721e_pcie_mode { > @@ -67,6 +69,9 @@ enum j721e_pcie_mode { > struct j721e_pcie_data { > enum j721e_pcie_mode mode; > bool quirk_retrain_flag; > + bool quirk_detect_quiet_flag; > + u32 link_irq_reg_field; > + bool byte_access_allowed; Maybe re-indent quirk_retrain_flag so the struct is consistent? I know there's a pattern of using "bool" in these structs, but I don't think it's really any better than "unsigned int :1" and it takes more space. https://lore.kernel.org/r/CA+55aFzKQ6Pj18TB8p4Yr0M4t+S+BsiHH=BJNmn=76-NcjTj-g@mail.gmail.com/ https://lore.kernel.org/r/CA+55aFxnePDimkVKVtv3gNmRGcwc8KQ5mHYvUxY8sAQg6yvVYg@mail.gmail.com/ > }; > > static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset) > @@ -98,12 +103,12 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv) > u32 reg; > > reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2); > - if (!(reg & LINK_DOWN)) > + if (!(reg & pcie->link_irq_reg_field)) > return IRQ_NONE; > > dev_err(dev, "LINK DOWN!\n"); > > - j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN); > + j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, pcie->link_irq_reg_field); > return IRQ_HANDLED; > } > > @@ -112,7 +117,7 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie) > u32 reg; > > reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2); > - reg |= LINK_DOWN; > + reg |= pcie->link_irq_reg_field; > j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg); > } > > @@ -284,10 +289,25 @@ static struct pci_ops cdns_ti_pcie_host_ops = { > static const struct j721e_pcie_data j721e_pcie_rc_data = { > .mode = PCI_MODE_RC, > .quirk_retrain_flag = true, > + .byte_access_allowed = false, > + .link_irq_reg_field = LINK_DOWN, > }; > > static const struct j721e_pcie_data j721e_pcie_ep_data = { > .mode = PCI_MODE_EP, > + .link_irq_reg_field = LINK_DOWN, > +}; > + > +static const struct j721e_pcie_data j7200_pcie_rc_data = { > + .mode = PCI_MODE_RC, > + .quirk_detect_quiet_flag = true, > + .link_irq_reg_field = J7200_LINK_DOWN, > + .byte_access_allowed = true, > +}; > + > +static const struct j721e_pcie_data j7200_pcie_ep_data = { > + .mode = PCI_MODE_EP, > + .quirk_detect_quiet_flag = true, > }; > > static const struct of_device_id of_j721e_pcie_match[] = { > @@ -299,6 +319,14 @@ static const struct of_device_id of_j721e_pcie_match[] = { > .compatible = "ti,j721e-pcie-ep", > .data = &j721e_pcie_ep_data, > }, > + { > + .compatible = "ti,j7200-pcie-host", > + .data = &j7200_pcie_rc_data, > + }, > + { > + .compatible = "ti,j7200-pcie-ep", > + .data = &j7200_pcie_ep_data, > + }, > {}, > }; > > @@ -309,10 +337,12 @@ static int j721e_pcie_probe(struct platform_device *pdev) > struct pci_host_bridge *bridge; > struct j721e_pcie_data *data; > struct cdns_pcie *cdns_pcie; > + bool byte_access_allowed; > struct j721e_pcie *pcie; > struct cdns_pcie_rc *rc; > struct cdns_pcie_ep *ep; > struct gpio_desc *gpiod; > + u32 link_irq_reg_field; > void __iomem *base; > struct clk *clk; > u32 num_lanes; > @@ -325,6 +355,8 @@ static int j721e_pcie_probe(struct platform_device *pdev) > return -EINVAL; > > mode = (u32)data->mode; > + byte_access_allowed = data->byte_access_allowed; > + link_irq_reg_field = data->link_irq_reg_field; > > pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); > if (!pcie) > @@ -332,6 +364,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) > > pcie->dev = dev; > pcie->mode = mode; > + pcie->link_irq_reg_field = link_irq_reg_field; > > base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg"); > if (IS_ERR(base)) > @@ -391,9 +424,11 @@ static int j721e_pcie_probe(struct platform_device *pdev) > goto err_get_sync; > } > > - bridge->ops = &cdns_ti_pcie_host_ops; > + if (!byte_access_allowed) Why bother with the "byte_access_allowed" local variable? Could just use "data->byte_access_allowed" here, as the code below uses "data->quirk_retrain_flag", etc. Same with "link_irq_reg_field" above, I guess. > + bridge->ops = &cdns_ti_pcie_host_ops; > rc = pci_host_bridge_priv(bridge); > rc->quirk_retrain_flag = data->quirk_retrain_flag; > + rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag; > > cdns_pcie = &rc->pcie; > cdns_pcie->dev = dev; > @@ -459,6 +494,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) > ret = -ENOMEM; > goto err_get_sync; > } > + ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag; > > cdns_pcie = &ep->pcie; > cdns_pcie->dev = dev; > -- > 2.17.1 >
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index 35e61048e133..803da33b86d8 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -27,6 +27,7 @@ #define STATUS_REG_SYS_2 0x508 #define STATUS_CLR_REG_SYS_2 0x708 #define LINK_DOWN BIT(1) +#define J7200_LINK_DOWN BIT(10) #define J721E_PCIE_USER_CMD_STATUS 0x4 #define LINK_TRAINING_ENABLE BIT(0) @@ -57,6 +58,7 @@ struct j721e_pcie { struct cdns_pcie *cdns_pcie; void __iomem *user_cfg_base; void __iomem *intd_cfg_base; + u32 link_irq_reg_field; }; enum j721e_pcie_mode { @@ -67,6 +69,9 @@ enum j721e_pcie_mode { struct j721e_pcie_data { enum j721e_pcie_mode mode; bool quirk_retrain_flag; + bool quirk_detect_quiet_flag; + u32 link_irq_reg_field; + bool byte_access_allowed; }; static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset) @@ -98,12 +103,12 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv) u32 reg; reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2); - if (!(reg & LINK_DOWN)) + if (!(reg & pcie->link_irq_reg_field)) return IRQ_NONE; dev_err(dev, "LINK DOWN!\n"); - j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN); + j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, pcie->link_irq_reg_field); return IRQ_HANDLED; } @@ -112,7 +117,7 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie) u32 reg; reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2); - reg |= LINK_DOWN; + reg |= pcie->link_irq_reg_field; j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg); } @@ -284,10 +289,25 @@ static struct pci_ops cdns_ti_pcie_host_ops = { static const struct j721e_pcie_data j721e_pcie_rc_data = { .mode = PCI_MODE_RC, .quirk_retrain_flag = true, + .byte_access_allowed = false, + .link_irq_reg_field = LINK_DOWN, }; static const struct j721e_pcie_data j721e_pcie_ep_data = { .mode = PCI_MODE_EP, + .link_irq_reg_field = LINK_DOWN, +}; + +static const struct j721e_pcie_data j7200_pcie_rc_data = { + .mode = PCI_MODE_RC, + .quirk_detect_quiet_flag = true, + .link_irq_reg_field = J7200_LINK_DOWN, + .byte_access_allowed = true, +}; + +static const struct j721e_pcie_data j7200_pcie_ep_data = { + .mode = PCI_MODE_EP, + .quirk_detect_quiet_flag = true, }; static const struct of_device_id of_j721e_pcie_match[] = { @@ -299,6 +319,14 @@ static const struct of_device_id of_j721e_pcie_match[] = { .compatible = "ti,j721e-pcie-ep", .data = &j721e_pcie_ep_data, }, + { + .compatible = "ti,j7200-pcie-host", + .data = &j7200_pcie_rc_data, + }, + { + .compatible = "ti,j7200-pcie-ep", + .data = &j7200_pcie_ep_data, + }, {}, }; @@ -309,10 +337,12 @@ static int j721e_pcie_probe(struct platform_device *pdev) struct pci_host_bridge *bridge; struct j721e_pcie_data *data; struct cdns_pcie *cdns_pcie; + bool byte_access_allowed; struct j721e_pcie *pcie; struct cdns_pcie_rc *rc; struct cdns_pcie_ep *ep; struct gpio_desc *gpiod; + u32 link_irq_reg_field; void __iomem *base; struct clk *clk; u32 num_lanes; @@ -325,6 +355,8 @@ static int j721e_pcie_probe(struct platform_device *pdev) return -EINVAL; mode = (u32)data->mode; + byte_access_allowed = data->byte_access_allowed; + link_irq_reg_field = data->link_irq_reg_field; pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); if (!pcie) @@ -332,6 +364,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) pcie->dev = dev; pcie->mode = mode; + pcie->link_irq_reg_field = link_irq_reg_field; base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg"); if (IS_ERR(base)) @@ -391,9 +424,11 @@ static int j721e_pcie_probe(struct platform_device *pdev) goto err_get_sync; } - bridge->ops = &cdns_ti_pcie_host_ops; + if (!byte_access_allowed) + bridge->ops = &cdns_ti_pcie_host_ops; rc = pci_host_bridge_priv(bridge); rc->quirk_retrain_flag = data->quirk_retrain_flag; + rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag; cdns_pcie = &rc->pcie; cdns_pcie->dev = dev; @@ -459,6 +494,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) ret = -ENOMEM; goto err_get_sync; } + ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag; cdns_pcie = &ep->pcie; cdns_pcie->dev = dev;
J7200 has the same PCIe IP as in J721E with minor changes in the wrapper. J7200 allows byte access of bridge configuration space registers and the register field for LINK_DOWN interrupt is different. J7200 also requires "quirk_detect_quiet_flag" to be set. Configure these changes as part of driver data applicable only to J7200. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> --- drivers/pci/controller/cadence/pci-j721e.c | 44 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-)