Lines Matching +full:uniphier +full:- +full:ld20 +full:- +full:usb3 +full:- +full:reset

1 // SPDX-License-Identifier: GPL-2.0
3 * phy-uniphier-usb3hs.c - HS-PHY driver for Socionext UniPhier USB3 controller
4 * Copyright 2015-2018 Socionext Inc.
17 #include <linux/nvmem-consumer.h>
23 #include <linux/reset.h>
66 #define trim_param_is_valid(p) ((p)->rterm || (p)->sel_t || (p)->hs_i)
92 *pconfig |= FIELD_PREP(HSPHY_CFG0_RTERM_MASK, pt->rterm); in uniphier_u3hsphy_trim_ld20()
95 *pconfig |= FIELD_PREP(HSPHY_CFG0_SEL_T_MASK, pt->sel_t); in uniphier_u3hsphy_trim_ld20()
98 *pconfig |= FIELD_PREP(HSPHY_CFG0_HS_I_MASK, pt->hs_i); in uniphier_u3hsphy_trim_ld20()
107 cell = devm_nvmem_cell_get(priv->dev, name); in uniphier_u3hsphy_get_nvparam()
127 ret = uniphier_u3hsphy_get_nvparam(priv, "rterm", &pt->rterm); in uniphier_u3hsphy_get_nvparams()
131 ret = uniphier_u3hsphy_get_nvparam(priv, "sel_t", &pt->sel_t); in uniphier_u3hsphy_get_nvparams()
135 ret = uniphier_u3hsphy_get_nvparam(priv, "hs_i", &pt->hs_i); in uniphier_u3hsphy_get_nvparams()
148 if (priv->data->trim_func) { in uniphier_u3hsphy_update_config()
150 if (ret == -EPROBE_DEFER) in uniphier_u3hsphy_update_config()
155 * all-zero can be acquired. All-zero parameters mean nothing in uniphier_u3hsphy_update_config()
159 priv->data->trim_func(priv, pconfig, &trim); in uniphier_u3hsphy_update_config()
162 dev_dbg(priv->dev, "can't get parameter from nvmem\n"); in uniphier_u3hsphy_update_config()
179 u32 field_mask = GENMASK(p->field.msb, p->field.lsb); in uniphier_u3hsphy_set_param()
182 val = readl(priv->base + HSPHY_CFG1); in uniphier_u3hsphy_set_param()
184 val |= FIELD_PREP(HSPHY_CFG1_ADR_MASK, p->field.reg_no) in uniphier_u3hsphy_set_param()
186 writel(val, priv->base + HSPHY_CFG1); in uniphier_u3hsphy_set_param()
188 val = readl(priv->base + HSPHY_CFG1); in uniphier_u3hsphy_set_param()
190 writel(val, priv->base + HSPHY_CFG1); in uniphier_u3hsphy_set_param()
192 val = readl(priv->base + HSPHY_CFG1); in uniphier_u3hsphy_set_param()
194 data = field_mask & (p->value << p->field.lsb); in uniphier_u3hsphy_set_param()
196 writel(val, priv->base + HSPHY_CFG1); in uniphier_u3hsphy_set_param()
198 val = readl(priv->base + HSPHY_CFG1); in uniphier_u3hsphy_set_param()
200 writel(val, priv->base + HSPHY_CFG1); in uniphier_u3hsphy_set_param()
208 ret = clk_prepare_enable(priv->clk_ext); in uniphier_u3hsphy_power_on()
212 ret = clk_prepare_enable(priv->clk); in uniphier_u3hsphy_power_on()
216 ret = reset_control_deassert(priv->rst); in uniphier_u3hsphy_power_on()
220 if (priv->vbus) { in uniphier_u3hsphy_power_on()
221 ret = regulator_enable(priv->vbus); in uniphier_u3hsphy_power_on()
229 reset_control_assert(priv->rst); in uniphier_u3hsphy_power_on()
231 clk_disable_unprepare(priv->clk); in uniphier_u3hsphy_power_on()
233 clk_disable_unprepare(priv->clk_ext); in uniphier_u3hsphy_power_on()
242 if (priv->vbus) in uniphier_u3hsphy_power_off()
243 regulator_disable(priv->vbus); in uniphier_u3hsphy_power_off()
245 reset_control_assert(priv->rst); in uniphier_u3hsphy_power_off()
246 clk_disable_unprepare(priv->clk); in uniphier_u3hsphy_power_off()
247 clk_disable_unprepare(priv->clk_ext); in uniphier_u3hsphy_power_off()
258 ret = clk_prepare_enable(priv->clk_parent); in uniphier_u3hsphy_init()
262 ret = clk_prepare_enable(priv->clk_parent_gio); in uniphier_u3hsphy_init()
266 ret = reset_control_deassert(priv->rst_parent); in uniphier_u3hsphy_init()
270 ret = reset_control_deassert(priv->rst_parent_gio); in uniphier_u3hsphy_init()
274 if ((priv->data->is_legacy) in uniphier_u3hsphy_init()
275 || (!priv->data->config0 && !priv->data->config1)) in uniphier_u3hsphy_init()
278 config0 = priv->data->config0; in uniphier_u3hsphy_init()
279 config1 = priv->data->config1; in uniphier_u3hsphy_init()
285 writel(config0, priv->base + HSPHY_CFG0); in uniphier_u3hsphy_init()
286 writel(config1, priv->base + HSPHY_CFG1); in uniphier_u3hsphy_init()
288 for (i = 0; i < priv->data->nparams; i++) in uniphier_u3hsphy_init()
289 uniphier_u3hsphy_set_param(priv, &priv->data->param[i]); in uniphier_u3hsphy_init()
294 reset_control_assert(priv->rst_parent); in uniphier_u3hsphy_init()
296 clk_disable_unprepare(priv->clk_parent_gio); in uniphier_u3hsphy_init()
298 clk_disable_unprepare(priv->clk_parent); in uniphier_u3hsphy_init()
307 reset_control_assert(priv->rst_parent_gio); in uniphier_u3hsphy_exit()
308 reset_control_assert(priv->rst_parent); in uniphier_u3hsphy_exit()
309 clk_disable_unprepare(priv->clk_parent_gio); in uniphier_u3hsphy_exit()
310 clk_disable_unprepare(priv->clk_parent); in uniphier_u3hsphy_exit()
325 struct device *dev = &pdev->dev; in uniphier_u3hsphy_probe()
332 return -ENOMEM; in uniphier_u3hsphy_probe()
334 priv->dev = dev; in uniphier_u3hsphy_probe()
335 priv->data = of_device_get_match_data(dev); in uniphier_u3hsphy_probe()
336 if (WARN_ON(!priv->data || in uniphier_u3hsphy_probe()
337 priv->data->nparams > MAX_PHY_PARAMS)) in uniphier_u3hsphy_probe()
338 return -EINVAL; in uniphier_u3hsphy_probe()
340 priv->base = devm_platform_ioremap_resource(pdev, 0); in uniphier_u3hsphy_probe()
341 if (IS_ERR(priv->base)) in uniphier_u3hsphy_probe()
342 return PTR_ERR(priv->base); in uniphier_u3hsphy_probe()
344 if (!priv->data->is_legacy) { in uniphier_u3hsphy_probe()
345 priv->clk = devm_clk_get(dev, "phy"); in uniphier_u3hsphy_probe()
346 if (IS_ERR(priv->clk)) in uniphier_u3hsphy_probe()
347 return PTR_ERR(priv->clk); in uniphier_u3hsphy_probe()
349 priv->clk_ext = devm_clk_get_optional(dev, "phy-ext"); in uniphier_u3hsphy_probe()
350 if (IS_ERR(priv->clk_ext)) in uniphier_u3hsphy_probe()
351 return PTR_ERR(priv->clk_ext); in uniphier_u3hsphy_probe()
353 priv->rst = devm_reset_control_get_shared(dev, "phy"); in uniphier_u3hsphy_probe()
354 if (IS_ERR(priv->rst)) in uniphier_u3hsphy_probe()
355 return PTR_ERR(priv->rst); in uniphier_u3hsphy_probe()
358 priv->clk_parent_gio = devm_clk_get(dev, "gio"); in uniphier_u3hsphy_probe()
359 if (IS_ERR(priv->clk_parent_gio)) in uniphier_u3hsphy_probe()
360 return PTR_ERR(priv->clk_parent_gio); in uniphier_u3hsphy_probe()
362 priv->rst_parent_gio = in uniphier_u3hsphy_probe()
364 if (IS_ERR(priv->rst_parent_gio)) in uniphier_u3hsphy_probe()
365 return PTR_ERR(priv->rst_parent_gio); in uniphier_u3hsphy_probe()
368 priv->clk_parent = devm_clk_get(dev, "link"); in uniphier_u3hsphy_probe()
369 if (IS_ERR(priv->clk_parent)) in uniphier_u3hsphy_probe()
370 return PTR_ERR(priv->clk_parent); in uniphier_u3hsphy_probe()
372 priv->rst_parent = devm_reset_control_get_shared(dev, "link"); in uniphier_u3hsphy_probe()
373 if (IS_ERR(priv->rst_parent)) in uniphier_u3hsphy_probe()
374 return PTR_ERR(priv->rst_parent); in uniphier_u3hsphy_probe()
376 priv->vbus = devm_regulator_get_optional(dev, "vbus"); in uniphier_u3hsphy_probe()
377 if (IS_ERR(priv->vbus)) { in uniphier_u3hsphy_probe()
378 if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) in uniphier_u3hsphy_probe()
379 return PTR_ERR(priv->vbus); in uniphier_u3hsphy_probe()
380 priv->vbus = NULL; in uniphier_u3hsphy_probe()
383 phy = devm_phy_create(dev, dev->of_node, &uniphier_u3hsphy_ops); in uniphier_u3hsphy_probe()
435 .compatible = "socionext,uniphier-pro5-usb3-hsphy",
439 .compatible = "socionext,uniphier-pxs2-usb3-hsphy",
443 .compatible = "socionext,uniphier-ld20-usb3-hsphy",
447 .compatible = "socionext,uniphier-pxs3-usb3-hsphy",
451 .compatible = "socionext,uniphier-nx1-usb3-hsphy",
461 .name = "uniphier-usb3-hsphy",
469 MODULE_DESCRIPTION("UniPhier HS-PHY driver for USB3 controller");