Lines Matching +full:pcie +full:- +full:phy +full:- +full:3

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2016-2018 Broadcom
12 #include <linux/phy/phy.h>
18 #define SR_PAXC_PHY_IDX (SR_NR_PCIE_PHYS - 1)
40 * struct sr_pcie_phy - Stingray PCIe PHY
42 * @core: pointer to the Stingray PCIe PHY core control
43 * @index: PHY index
44 * @phy: pointer to the kernel PHY device
49 struct phy *phy; member
53 * struct sr_pcie_phy_core - Stingray PCIe PHY core control
56 * @base: base register of PCIe SS
60 * @phys: array of PCIe PHYs
72 * PCIe PIPEMUX lookup table
75 * The array element represents a bitmap where a set bit means the PCIe
85 /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
91 /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
93 /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
101 /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
103 /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
105 /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
118 * Read the PCIe PIPEMUX from strap
130 pipemux = readl(core->base + PCIE_PIPEMUX_CFG_OFFSET); in pipemux_strap_read()
133 regmap_read(core->cdru, CDRU_STRAP_DATA_LSW_OFFSET, &pipemux); in pipemux_strap_read()
142 * Given a PIPEMUX strap and PCIe core index, this function returns true if the
143 * PCIe core needs to be enabled
145 static bool pcie_core_is_for_rc(struct sr_pcie_phy *phy) in pcie_core_is_for_rc() argument
147 struct sr_pcie_phy_core *core = phy->core; in pcie_core_is_for_rc()
148 unsigned int core_idx = phy->index; in pcie_core_is_for_rc()
150 return !!((pipemux_table[core->pipemux] >> core_idx) & 0x1); in pcie_core_is_for_rc()
153 static int sr_pcie_phy_init(struct phy *p) in sr_pcie_phy_init()
155 struct sr_pcie_phy *phy = phy_get_drvdata(p); in sr_pcie_phy_init() local
158 * Check whether this PHY is for root complex or not. If yes, return in sr_pcie_phy_init()
162 if (pcie_core_is_for_rc(phy)) in sr_pcie_phy_init()
165 return -ENODEV; in sr_pcie_phy_init()
168 static int sr_paxc_phy_init(struct phy *p) in sr_paxc_phy_init()
170 struct sr_pcie_phy *phy = phy_get_drvdata(p); in sr_paxc_phy_init() local
171 struct sr_pcie_phy_core *core = phy->core; in sr_paxc_phy_init()
172 unsigned int core_idx = phy->index; in sr_paxc_phy_init()
176 return -EINVAL; in sr_paxc_phy_init()
178 regmap_read(core->mhb, MHB_MEM_PW_PAXC_OFFSET, &val); in sr_paxc_phy_init()
180 dev_err(core->dev, "PAXC is not powered up\n"); in sr_paxc_phy_init()
181 return -ENODEV; in sr_paxc_phy_init()
197 static struct phy *sr_pcie_phy_xlate(struct device *dev, in sr_pcie_phy_xlate()
205 return ERR_PTR(-EINVAL); in sr_pcie_phy_xlate()
207 phy_idx = args->args[0]; in sr_pcie_phy_xlate()
210 return ERR_PTR(-ENODEV); in sr_pcie_phy_xlate()
212 return core->phys[phy_idx].phy; in sr_pcie_phy_xlate()
217 struct device *dev = &pdev->dev; in sr_pcie_phy_probe()
218 struct device_node *node = dev->of_node; in sr_pcie_phy_probe()
225 return -ENOMEM; in sr_pcie_phy_probe()
227 core->dev = dev; in sr_pcie_phy_probe()
228 core->base = devm_platform_ioremap_resource(pdev, 0); in sr_pcie_phy_probe()
229 if (IS_ERR(core->base)) in sr_pcie_phy_probe()
230 return PTR_ERR(core->base); in sr_pcie_phy_probe()
232 core->cdru = syscon_regmap_lookup_by_phandle(node, "brcm,sr-cdru"); in sr_pcie_phy_probe()
233 if (IS_ERR(core->cdru)) { in sr_pcie_phy_probe()
234 dev_err(core->dev, "unable to find CDRU device\n"); in sr_pcie_phy_probe()
235 return PTR_ERR(core->cdru); in sr_pcie_phy_probe()
238 core->mhb = syscon_regmap_lookup_by_phandle(node, "brcm,sr-mhb"); in sr_pcie_phy_probe()
239 if (IS_ERR(core->mhb)) { in sr_pcie_phy_probe()
240 dev_err(core->dev, "unable to find MHB device\n"); in sr_pcie_phy_probe()
241 return PTR_ERR(core->mhb); in sr_pcie_phy_probe()
244 /* read the PCIe PIPEMUX strap setting */ in sr_pcie_phy_probe()
245 core->pipemux = pipemux_strap_read(core); in sr_pcie_phy_probe()
246 if (!pipemux_strap_is_valid(core->pipemux)) { in sr_pcie_phy_probe()
247 dev_err(core->dev, "invalid PCIe PIPEMUX strap %u\n", in sr_pcie_phy_probe()
248 core->pipemux); in sr_pcie_phy_probe()
249 return -EIO; in sr_pcie_phy_probe()
253 struct sr_pcie_phy *p = &core->phys[phy_idx]; in sr_pcie_phy_probe()
261 p->phy = devm_phy_create(dev, NULL, ops); in sr_pcie_phy_probe()
262 if (IS_ERR(p->phy)) { in sr_pcie_phy_probe()
263 dev_err(dev, "failed to create PCIe PHY\n"); in sr_pcie_phy_probe()
264 return PTR_ERR(p->phy); in sr_pcie_phy_probe()
267 p->core = core; in sr_pcie_phy_probe()
268 p->index = phy_idx; in sr_pcie_phy_probe()
269 phy_set_drvdata(p->phy, p); in sr_pcie_phy_probe()
276 dev_err(dev, "failed to register PHY provider\n"); in sr_pcie_phy_probe()
280 dev_info(dev, "Stingray PCIe PHY driver initialized\n"); in sr_pcie_phy_probe()
286 { .compatible = "brcm,sr-pcie-phy" },
293 .name = "sr-pcie-phy",
301 MODULE_DESCRIPTION("Broadcom Stingray PCIe PHY driver");