reg = <0x0 0x17010000 0x0 0x1000>;
};
+ phyctrl0: multi-phyctrl@10210000 {
+ compatible = "starfive,phyctrl";
+ reg = <0x0 0x10210000 0x0 0x10000>;
+ };
+
+ phyctrl1: pcie1-phyctrl@10220000 {
+ compatible = "starfive,phyctrl";
+ reg = <0x0 0x10220000 0x0 0x10000>;
+ };
+
stg_syscon: stg_syscon@10240000 {
compatible = "syscon";
reg = <0x0 0x10240000 0x0 0x1000>;
reg-names = "reg", "config";
device_type = "pci";
starfive,stg-syscon = <&stg_syscon 0xc0 0xc4 0x130 0x1b8>;
+ starfive,phyctrl = <&phyctrl0 0x28 0x80>;
bus-range = <0x0 0xff>;
ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
<0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
reg-names = "reg", "config";
device_type = "pci";
starfive,stg-syscon = <&stg_syscon 0x270 0x274 0x2e0 0x368>;
+ starfive,phyctrl = <&phyctrl1 0x28 0x80>;
bus-range = <0x0 0xff>;
ranges = <0x82000000 0x0 0x38000000 0x0 0x38000000 0x0 0x08000000>,
<0xc3000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>;
#define PLDA_FUNCTION_DIS BIT(15)
#define PLDA_FUNC_NUM 4
#define PLDA_PHY_FUNC_SHIFT 9
+#define PHY_KVCO_FINE_TUNE_LEVEL 0x91
+#define PHY_KVCO_FINE_TUNE_SIGNALS 0xc
#define XR3PCI_ATR_AXI4_SLV0 0x800
#define XR3PCI_ATR_SRC_ADDR_LOW 0x0
void __iomem *config_base;
struct resource *cfg_res;
struct regmap *reg_syscon;
+ struct regmap *reg_phyctrl;
u32 stg_arfun;
u32 stg_awfun;
u32 stg_rp_nep;
u32 stg_lnksta;
+ u32 phy_kvco_level;
+ u32 phy_kvco_tune_signals;
int irq;
struct irq_domain *legacy_irq_domain;
struct pci_host_bridge *bridge;
{
struct resource *reg_res;
struct platform_device *pdev = pcie->pdev;
- struct of_phandle_args args;
+ struct of_phandle_args syscon_args, phyctrl_args;
int ret;
reg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
return PTR_ERR(pcie->config_base);
}
+ ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
+ "starfive,phyctrl", 2, 0, &phyctrl_args);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to parse starfive,phyctrl\n");
+ return -EINVAL;
+ }
+
+ if (!of_device_is_compatible(phyctrl_args.np, "starfive,phyctrl"))
+ return -EINVAL;
+ pcie->reg_phyctrl = device_node_to_regmap(phyctrl_args.np);
+ of_node_put(phyctrl_args.np);
+ if (IS_ERR(pcie->reg_phyctrl))
+ return PTR_ERR(pcie->reg_phyctrl);
+
+ pcie->phy_kvco_level = phyctrl_args.args[0];
+ pcie->phy_kvco_tune_signals = phyctrl_args.args[1];
+
pcie->irq = platform_get_irq(pdev, 0);
if (pcie->irq <= 0) {
dev_err(&pdev->dev, "Failed to get IRQ: %d\n", pcie->irq);
}
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
- "starfive,stg-syscon", 4, 0, &args);
+ "starfive,stg-syscon", 4, 0, &syscon_args);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to parse starfive,stg-syscon\n");
return -EINVAL;
}
- pcie->reg_syscon = syscon_node_to_regmap(args.np);
- of_node_put(args.np);
+ pcie->reg_syscon = syscon_node_to_regmap(syscon_args.np);
+ of_node_put(syscon_args.np);
if (IS_ERR(pcie->reg_syscon))
return PTR_ERR(pcie->reg_syscon);
- pcie->stg_arfun = args.args[0];
- pcie->stg_awfun = args.args[1];
- pcie->stg_rp_nep = args.args[2];
- pcie->stg_lnksta = args.args[3];
+ pcie->stg_arfun = syscon_args.args[0];
+ pcie->stg_awfun = syscon_args.args[1];
+ pcie->stg_rp_nep = syscon_args.args[2];
+ pcie->stg_lnksta = syscon_args.args[3];
/* Clear all interrupts */
plda_writel(pcie, 0xffffffff, ISTATUS_LOCAL);
STG_SYSCON_AXI4_SLVL_AWFUNC_MASK,
0 << STG_SYSCON_AXI4_SLVL_AWFUNC_SHIFT);
+ /* PCIe Multi-PHY PLL KVCO Gain fine tune settings: */
+ regmap_write(pcie->reg_phyctrl, pcie->phy_kvco_level,
+ PHY_KVCO_FINE_TUNE_LEVEL);
+ regmap_write(pcie->reg_phyctrl, pcie->phy_kvco_tune_signals,
+ PHY_KVCO_FINE_TUNE_SIGNALS);
+
/* Enable root port*/
value = readl(pcie->reg_base + GEN_SETTINGS);
value |= PLDA_RP_ENABLE;