Lines Matching +full:jz4770 +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0
3 * Ingenic SoCs USB PHY driver
15 #include <linux/usb/phy.h>
100 void (*usb_phy_init)(struct usb_phy *phy);
106 struct usb_phy phy; member
119 static inline struct jz4770_phy *phy_to_jz4770_phy(struct usb_phy *phy) in phy_to_jz4770_phy() argument
121 return container_of(phy, struct jz4770_phy, phy); in phy_to_jz4770_phy()
130 if (priv->soc_info->version >= ID_X1000) { in ingenic_usb_phy_set_peripheral()
131 reg = readl(priv->base + REG_USBPCR1_OFFSET); in ingenic_usb_phy_set_peripheral()
133 writel(reg, priv->base + REG_USBPCR1_OFFSET); in ingenic_usb_phy_set_peripheral()
136 reg = readl(priv->base + REG_USBPCR_OFFSET); in ingenic_usb_phy_set_peripheral()
139 writel(reg, priv->base + REG_USBPCR_OFFSET); in ingenic_usb_phy_set_peripheral()
149 reg = readl(priv->base + REG_USBPCR_OFFSET); in ingenic_usb_phy_set_host()
152 writel(reg, priv->base + REG_USBPCR_OFFSET); in ingenic_usb_phy_set_host()
157 static int ingenic_usb_phy_init(struct usb_phy *phy) in ingenic_usb_phy_init() argument
159 struct jz4770_phy *priv = phy_to_jz4770_phy(phy); in ingenic_usb_phy_init()
163 err = regulator_enable(priv->vcc_supply); in ingenic_usb_phy_init()
165 dev_err(priv->dev, "Unable to enable VCC: %d\n", err); in ingenic_usb_phy_init()
169 err = clk_prepare_enable(priv->clk); in ingenic_usb_phy_init()
171 dev_err(priv->dev, "Unable to start clock: %d\n", err); in ingenic_usb_phy_init()
175 priv->soc_info->usb_phy_init(phy); in ingenic_usb_phy_init()
177 /* Wait for PHY to reset */ in ingenic_usb_phy_init()
179 reg = readl(priv->base + REG_USBPCR_OFFSET); in ingenic_usb_phy_init()
180 writel(reg & ~USBPCR_POR, priv->base + REG_USBPCR_OFFSET); in ingenic_usb_phy_init()
186 static void ingenic_usb_phy_shutdown(struct usb_phy *phy) in ingenic_usb_phy_shutdown() argument
188 struct jz4770_phy *priv = phy_to_jz4770_phy(phy); in ingenic_usb_phy_shutdown()
190 clk_disable_unprepare(priv->clk); in ingenic_usb_phy_shutdown()
191 regulator_disable(priv->vcc_supply); in ingenic_usb_phy_shutdown()
194 static void ingenic_usb_phy_remove(void *phy) in ingenic_usb_phy_remove() argument
196 usb_remove_phy(phy); in ingenic_usb_phy_remove()
199 static void jz4770_usb_phy_init(struct usb_phy *phy) in jz4770_usb_phy_init() argument
201 struct jz4770_phy *priv = phy_to_jz4770_phy(phy); in jz4770_usb_phy_init()
208 writel(reg, priv->base + REG_USBPCR_OFFSET); in jz4770_usb_phy_init()
211 static void jz4780_usb_phy_init(struct usb_phy *phy) in jz4780_usb_phy_init() argument
213 struct jz4770_phy *priv = phy_to_jz4770_phy(phy); in jz4780_usb_phy_init()
216 reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_USB_SEL | in jz4780_usb_phy_init()
218 writel(reg, priv->base + REG_USBPCR1_OFFSET); in jz4780_usb_phy_init()
221 writel(reg, priv->base + REG_USBPCR_OFFSET); in jz4780_usb_phy_init()
224 static void x1000_usb_phy_init(struct usb_phy *phy) in x1000_usb_phy_init() argument
226 struct jz4770_phy *priv = phy_to_jz4770_phy(phy); in x1000_usb_phy_init()
229 reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_WORD_IF_16BIT; in x1000_usb_phy_init()
230 writel(reg, priv->base + REG_USBPCR1_OFFSET); in x1000_usb_phy_init()
235 writel(reg, priv->base + REG_USBPCR_OFFSET); in x1000_usb_phy_init()
238 static void x1830_usb_phy_init(struct usb_phy *phy) in x1830_usb_phy_init() argument
240 struct jz4770_phy *priv = phy_to_jz4770_phy(phy); in x1830_usb_phy_init()
244 writel(USBRDT_VBFIL_EN | USBRDT_UTMI_RST, priv->base + REG_USBRDT_OFFSET); in x1830_usb_phy_init()
246 reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_WORD_IF_16BIT | in x1830_usb_phy_init()
248 writel(reg, priv->base + REG_USBPCR1_OFFSET); in x1830_usb_phy_init()
252 writel(reg, priv->base + REG_USBPCR_OFFSET); in x1830_usb_phy_init()
280 { .compatible = "ingenic,jz4770-phy", .data = &jz4770_soc_info },
281 { .compatible = "ingenic,jz4780-phy", .data = &jz4780_soc_info },
282 { .compatible = "ingenic,x1000-phy", .data = &x1000_soc_info },
283 { .compatible = "ingenic,x1830-phy", .data = &x1830_soc_info },
290 struct device *dev = &pdev->dev; in jz4770_phy_probe()
296 return -ENOMEM; in jz4770_phy_probe()
298 priv->soc_info = device_get_match_data(&pdev->dev); in jz4770_phy_probe()
299 if (!priv->soc_info) { in jz4770_phy_probe()
300 dev_err(&pdev->dev, "Error: No device match found\n"); in jz4770_phy_probe()
301 return -ENODEV; in jz4770_phy_probe()
305 priv->dev = dev; in jz4770_phy_probe()
306 priv->phy.dev = dev; in jz4770_phy_probe()
307 priv->phy.otg = &priv->otg; in jz4770_phy_probe()
308 priv->phy.label = "ingenic-usb-phy"; in jz4770_phy_probe()
309 priv->phy.init = ingenic_usb_phy_init; in jz4770_phy_probe()
310 priv->phy.shutdown = ingenic_usb_phy_shutdown; in jz4770_phy_probe()
312 priv->otg.state = OTG_STATE_UNDEFINED; in jz4770_phy_probe()
313 priv->otg.usb_phy = &priv->phy; in jz4770_phy_probe()
314 priv->otg.set_host = ingenic_usb_phy_set_host; in jz4770_phy_probe()
315 priv->otg.set_peripheral = ingenic_usb_phy_set_peripheral; in jz4770_phy_probe()
317 priv->base = devm_platform_ioremap_resource(pdev, 0); in jz4770_phy_probe()
318 if (IS_ERR(priv->base)) { in jz4770_phy_probe()
320 return PTR_ERR(priv->base); in jz4770_phy_probe()
323 priv->clk = devm_clk_get(dev, NULL); in jz4770_phy_probe()
324 if (IS_ERR(priv->clk)) in jz4770_phy_probe()
325 return dev_err_probe(dev, PTR_ERR(priv->clk), in jz4770_phy_probe()
328 priv->vcc_supply = devm_regulator_get(dev, "vcc"); in jz4770_phy_probe()
329 if (IS_ERR(priv->vcc_supply)) in jz4770_phy_probe()
330 return dev_err_probe(dev, PTR_ERR(priv->vcc_supply), in jz4770_phy_probe()
333 err = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); in jz4770_phy_probe()
335 return dev_err_probe(dev, err, "Unable to register PHY\n"); in jz4770_phy_probe()
337 return devm_add_action_or_reset(dev, ingenic_usb_phy_remove, &priv->phy); in jz4770_phy_probe()
343 .name = "jz4770-phy",
352 MODULE_DESCRIPTION("Ingenic SoCs USB PHY driver");