blob: ceed1911a95a99dbdd893ba305bea3f517ba23f2 [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
6#include <common.h>
Patrice Chotard37a197a2017-07-18 11:57:12 +02007#include <clk.h>
Alexey Brodkin83fd3122015-12-14 17:18:50 +03008#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -070010#include <dm/device_compat.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070011#include <dm/devres.h>
Patrice Chotard37a197a2017-07-18 11:57:12 +020012#include <dm/ofnode.h>
Patrice Chotardc6e19d32017-07-18 11:57:14 +020013#include <generic-phy.h>
Patrice Chotard170229e2017-07-18 11:57:13 +020014#include <reset.h>
Alexey Brodkin83fd3122015-12-14 17:18:50 +030015#include "ohci.h"
16
Alexey Brodkin83fd3122015-12-14 17:18:50 +030017struct generic_ohci {
18 ohci_t ohci;
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020019 struct clk_bulk clocks; /* clock list */
20 struct reset_ctl_bulk resets; /* reset list */
Patrice Chotardc6e19d32017-07-18 11:57:14 +020021 struct phy phy;
Alexey Brodkin83fd3122015-12-14 17:18:50 +030022};
23
24static int ohci_usb_probe(struct udevice *dev)
25{
Masahiro Yamada1096ae12020-07-17 14:36:46 +090026 struct ohci_regs *regs = dev_read_addr_ptr(dev);
Patrice Chotard37a197a2017-07-18 11:57:12 +020027 struct generic_ohci *priv = dev_get_priv(dev);
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020028 int err, ret;
Alexey Brodkin83fd3122015-12-14 17:18:50 +030029
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020030 ret = clk_get_bulk(dev, &priv->clocks);
31 if (ret && ret != -ENOENT) {
32 dev_err(dev, "Failed to get clocks (ret=%d)\n", ret);
33 return ret;
Patrice Chotard37a197a2017-07-18 11:57:12 +020034 }
35
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020036 err = clk_enable_bulk(&priv->clocks);
37 if (err) {
38 dev_err(dev, "Failed to enable clocks (err=%d)\n", err);
39 goto clk_err;
40 }
Patrice Chotard170229e2017-07-18 11:57:13 +020041
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020042 err = reset_get_bulk(dev, &priv->resets);
43 if (err && err != -ENOENT) {
44 dev_err(dev, "failed to get resets (err=%d)\n", err);
Patrice Chotard170229e2017-07-18 11:57:13 +020045 goto clk_err;
46 }
47
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020048 err = reset_deassert_bulk(&priv->resets);
49 if (err) {
50 dev_err(dev, "failed to deassert resets (err=%d)\n", err);
51 goto reset_err;
52 }
53
Patrice Chotardcb9f1e42022-09-06 08:15:27 +020054 err = generic_setup_phy(dev, &priv->phy, 0);
Patrice Chotardab0b205e2018-03-14 17:48:57 +010055 if (err)
Patrice Chotardab0b205e2018-03-14 17:48:57 +010056 goto reset_err;
Patrice Chotardc6e19d32017-07-18 11:57:14 +020057
Patrice Chotard37a197a2017-07-18 11:57:12 +020058 err = ohci_register(dev, regs);
59 if (err)
Patrice Chotardc6e19d32017-07-18 11:57:14 +020060 goto phy_err;
Patrice Chotard37a197a2017-07-18 11:57:12 +020061
62 return 0;
63
Patrice Chotardc6e19d32017-07-18 11:57:14 +020064phy_err:
Patrice Chotardcb9f1e42022-09-06 08:15:27 +020065 ret = generic_shutdown_phy(&priv->phy);
Patrice Chotardab0b205e2018-03-14 17:48:57 +010066 if (ret)
67 dev_err(dev, "failed to shutdown usb phy\n");
Patrice Chotardc6e19d32017-07-18 11:57:14 +020068
Patrice Chotard170229e2017-07-18 11:57:13 +020069reset_err:
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020070 ret = reset_release_bulk(&priv->resets);
Patrice Chotard170229e2017-07-18 11:57:13 +020071 if (ret)
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020072 dev_err(dev, "failed to release resets (ret=%d)\n", ret);
Patrice Chotard37a197a2017-07-18 11:57:12 +020073clk_err:
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020074 ret = clk_release_bulk(&priv->clocks);
Patrice Chotard37a197a2017-07-18 11:57:12 +020075 if (ret)
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020076 dev_err(dev, "failed to release clocks (ret=%d)\n", ret);
Patrice Chotard37a197a2017-07-18 11:57:12 +020077
78 return err;
Alexey Brodkin83fd3122015-12-14 17:18:50 +030079}
80
81static int ohci_usb_remove(struct udevice *dev)
82{
Patrice Chotard37a197a2017-07-18 11:57:12 +020083 struct generic_ohci *priv = dev_get_priv(dev);
84 int ret;
85
86 ret = ohci_deregister(dev);
87 if (ret)
88 return ret;
89
Patrice Chotardcb9f1e42022-09-06 08:15:27 +020090 ret = generic_shutdown_phy(&priv->phy);
Patrice Chotardab0b205e2018-03-14 17:48:57 +010091 if (ret)
92 return ret;
Patrice Chotardc6e19d32017-07-18 11:57:14 +020093
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020094 ret = reset_release_bulk(&priv->resets);
Patrice Chotard170229e2017-07-18 11:57:13 +020095 if (ret)
96 return ret;
97
Fabrice Gasnier19a383a2023-09-04 14:20:21 +020098 return clk_release_bulk(&priv->clocks);
Alexey Brodkin83fd3122015-12-14 17:18:50 +030099}
100
101static const struct udevice_id ohci_usb_ids[] = {
102 { .compatible = "generic-ohci" },
103 { }
104};
105
106U_BOOT_DRIVER(ohci_generic) = {
107 .name = "ohci_generic",
108 .id = UCLASS_USB,
109 .of_match = ohci_usb_ids,
110 .probe = ohci_usb_probe,
111 .remove = ohci_usb_remove,
112 .ops = &ohci_usb_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700113 .priv_auto = sizeof(struct generic_ohci),
Alexey Brodkin83fd3122015-12-14 17:18:50 +0300114 .flags = DM_FLAG_ALLOC_PRIV_DMA,
115};