blob: f1325cd4953430ba98a2709461627c78f693667b [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Alexey Brodkin83fd3122015-12-14 17:18:50 +03002/*
3 * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
Alexey Brodkin83fd3122015-12-14 17:18:50 +03004 */
5
Patrice Chotard37a197a2017-07-18 11:57:12 +02006#include <clk.h>
Alexey Brodkin83fd3122015-12-14 17:18:50 +03007#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -06008#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -07009#include <dm/device_compat.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070010#include <dm/devres.h>
Patrice Chotard37a197a2017-07-18 11:57:12 +020011#include <dm/ofnode.h>
Patrice Chotardc6e19d32017-07-18 11:57:14 +020012#include <generic-phy.h>
Patrice Chotard170229e2017-07-18 11:57:13 +020013#include <reset.h>
Alexey Brodkin83fd3122015-12-14 17:18:50 +030014#include "ohci.h"
15
Alexey Brodkin83fd3122015-12-14 17:18:50 +030016struct generic_ohci {
17 ohci_t ohci;
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020018 struct clk_bulk clocks; /* clock list */
19 struct reset_ctl_bulk resets; /* reset list */
Patrice Chotardc6e19d32017-07-18 11:57:14 +020020 struct phy phy;
Alexey Brodkin83fd3122015-12-14 17:18:50 +030021};
22
23static int ohci_usb_probe(struct udevice *dev)
24{
Masahiro Yamada1096ae12020-07-17 14:36:46 +090025 struct ohci_regs *regs = dev_read_addr_ptr(dev);
Patrice Chotard37a197a2017-07-18 11:57:12 +020026 struct generic_ohci *priv = dev_get_priv(dev);
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020027 int err, ret;
Alexey Brodkin83fd3122015-12-14 17:18:50 +030028
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020029 ret = clk_get_bulk(dev, &priv->clocks);
30 if (ret && ret != -ENOENT) {
31 dev_err(dev, "Failed to get clocks (ret=%d)\n", ret);
32 return ret;
Patrice Chotard37a197a2017-07-18 11:57:12 +020033 }
34
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020035 err = clk_enable_bulk(&priv->clocks);
36 if (err) {
37 dev_err(dev, "Failed to enable clocks (err=%d)\n", err);
38 goto clk_err;
39 }
Patrice Chotard170229e2017-07-18 11:57:13 +020040
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020041 err = reset_get_bulk(dev, &priv->resets);
42 if (err && err != -ENOENT) {
43 dev_err(dev, "failed to get resets (err=%d)\n", err);
Patrice Chotard170229e2017-07-18 11:57:13 +020044 goto clk_err;
45 }
46
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020047 err = reset_deassert_bulk(&priv->resets);
48 if (err) {
49 dev_err(dev, "failed to deassert resets (err=%d)\n", err);
50 goto reset_err;
51 }
52
Patrice Chotardcb9f1e42022-09-06 08:15:27 +020053 err = generic_setup_phy(dev, &priv->phy, 0);
Patrice Chotardab0b205e2018-03-14 17:48:57 +010054 if (err)
Patrice Chotardab0b205e2018-03-14 17:48:57 +010055 goto reset_err;
Patrice Chotardc6e19d32017-07-18 11:57:14 +020056
Patrice Chotard37a197a2017-07-18 11:57:12 +020057 err = ohci_register(dev, regs);
58 if (err)
Patrice Chotardc6e19d32017-07-18 11:57:14 +020059 goto phy_err;
Patrice Chotard37a197a2017-07-18 11:57:12 +020060
61 return 0;
62
Patrice Chotardc6e19d32017-07-18 11:57:14 +020063phy_err:
Patrice Chotardcb9f1e42022-09-06 08:15:27 +020064 ret = generic_shutdown_phy(&priv->phy);
Patrice Chotardab0b205e2018-03-14 17:48:57 +010065 if (ret)
66 dev_err(dev, "failed to shutdown usb phy\n");
Patrice Chotardc6e19d32017-07-18 11:57:14 +020067
Patrice Chotard170229e2017-07-18 11:57:13 +020068reset_err:
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020069 ret = reset_release_bulk(&priv->resets);
Patrice Chotard170229e2017-07-18 11:57:13 +020070 if (ret)
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020071 dev_err(dev, "failed to release resets (ret=%d)\n", ret);
Patrice Chotard37a197a2017-07-18 11:57:12 +020072clk_err:
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020073 ret = clk_release_bulk(&priv->clocks);
Patrice Chotard37a197a2017-07-18 11:57:12 +020074 if (ret)
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020075 dev_err(dev, "failed to release clocks (ret=%d)\n", ret);
Patrice Chotard37a197a2017-07-18 11:57:12 +020076
77 return err;
Alexey Brodkin83fd3122015-12-14 17:18:50 +030078}
79
80static int ohci_usb_remove(struct udevice *dev)
81{
Patrice Chotard37a197a2017-07-18 11:57:12 +020082 struct generic_ohci *priv = dev_get_priv(dev);
83 int ret;
84
85 ret = ohci_deregister(dev);
86 if (ret)
87 return ret;
88
Patrice Chotardcb9f1e42022-09-06 08:15:27 +020089 ret = generic_shutdown_phy(&priv->phy);
Patrice Chotardab0b205e2018-03-14 17:48:57 +010090 if (ret)
91 return ret;
Patrice Chotardc6e19d32017-07-18 11:57:14 +020092
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020093 ret = reset_release_bulk(&priv->resets);
Patrice Chotard170229e2017-07-18 11:57:13 +020094 if (ret)
95 return ret;
96
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020097 return clk_release_bulk(&priv->clocks);
Alexey Brodkin83fd3122015-12-14 17:18:50 +030098}
99
100static const struct udevice_id ohci_usb_ids[] = {
101 { .compatible = "generic-ohci" },
102 { }
103};
104
105U_BOOT_DRIVER(ohci_generic) = {
106 .name = "ohci_generic",
107 .id = UCLASS_USB,
108 .of_match = ohci_usb_ids,
109 .probe = ohci_usb_probe,
110 .remove = ohci_usb_remove,
111 .ops = &ohci_usb_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700112 .priv_auto = sizeof(struct generic_ohci),
Alexey Brodkin83fd3122015-12-14 17:18:50 +0300113 .flags = DM_FLAG_ALLOC_PRIV_DMA,
114};