blob: ab85428a7003b9f1487b00e2881fb20cd7aa198c [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Masahiro Yamadaa50bab32017-09-28 22:01:00 +09002/*
3 * UniPhier Specific Glue Layer for DWC3
4 *
5 * Copyright (C) 2016-2017 Socionext Inc.
6 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
Kunihiko Hayashic891a462023-02-20 14:50:33 +09007 * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Masahiro Yamadaa50bab32017-09-28 22:01:00 +09008 */
9
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090010#include <dm.h>
Kunihiko Hayashic891a462023-02-20 14:50:33 +090011#include <dm/lists.h>
Masahiro Yamada0da3db92017-10-13 19:21:56 +090012#include <linux/bitops.h>
Kunihiko Hayashic891a462023-02-20 14:50:33 +090013#include <linux/usb/gadget.h>
14
15#include "core.h"
16#include "gadget.h"
17#include "dwc3-generic.h"
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090018
19#define UNIPHIER_PRO4_DWC3_RESET 0x40
20#define UNIPHIER_PRO4_DWC3_RESET_XIOMMU BIT(5)
21#define UNIPHIER_PRO4_DWC3_RESET_XLINK BIT(4)
22#define UNIPHIER_PRO4_DWC3_RESET_PHY_SS BIT(2)
23
24#define UNIPHIER_PRO5_DWC3_RESET 0x00
25#define UNIPHIER_PRO5_DWC3_RESET_PHY_S1 BIT(17)
26#define UNIPHIER_PRO5_DWC3_RESET_PHY_S0 BIT(16)
27#define UNIPHIER_PRO5_DWC3_RESET_XLINK BIT(15)
28#define UNIPHIER_PRO5_DWC3_RESET_XIOMMU BIT(14)
29
30#define UNIPHIER_PXS2_DWC3_RESET 0x00
31#define UNIPHIER_PXS2_DWC3_RESET_XLINK BIT(15)
32
Kunihiko Hayashic891a462023-02-20 14:50:33 +090033static void uniphier_pro4_dwc3_init(struct udevice *dev, int index,
34 enum usb_dr_mode mode)
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090035{
Kunihiko Hayashic891a462023-02-20 14:50:33 +090036 struct dwc3_glue_data *glue = dev_get_plat(dev);
37 void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090038 u32 tmp;
39
40 tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
41 tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS;
42 tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
43 writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
44
Kunihiko Hayashic891a462023-02-20 14:50:33 +090045 unmap_physmem(regs, MAP_NOCACHE);
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090046}
47
Kunihiko Hayashic891a462023-02-20 14:50:33 +090048static void uniphier_pro5_dwc3_init(struct udevice *dev, int index,
49 enum usb_dr_mode mode)
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090050{
Kunihiko Hayashic891a462023-02-20 14:50:33 +090051 struct dwc3_glue_data *glue = dev_get_plat(dev);
52 void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090053 u32 tmp;
54
55 tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET);
56 tmp &= ~(UNIPHIER_PRO5_DWC3_RESET_PHY_S1 |
57 UNIPHIER_PRO5_DWC3_RESET_PHY_S0);
58 tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU;
59 writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET);
60
Kunihiko Hayashic891a462023-02-20 14:50:33 +090061 unmap_physmem(regs, MAP_NOCACHE);
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090062}
63
Kunihiko Hayashic891a462023-02-20 14:50:33 +090064static void uniphier_pxs2_dwc3_init(struct udevice *dev, int index,
65 enum usb_dr_mode mode)
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090066{
Kunihiko Hayashic891a462023-02-20 14:50:33 +090067 struct dwc3_glue_data *glue = dev_get_plat(dev);
68 void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090069 u32 tmp;
70
71 tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET);
72 tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK;
73 writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET);
74
Kunihiko Hayashic891a462023-02-20 14:50:33 +090075 unmap_physmem(regs, MAP_NOCACHE);
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090076}
77
Kunihiko Hayashic891a462023-02-20 14:50:33 +090078static int dwc3_uniphier_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090079{
Kunihiko Hayashic891a462023-02-20 14:50:33 +090080 struct udevice *child;
81 const char *name;
82 ofnode subnode;
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090083
Kunihiko Hayashic891a462023-02-20 14:50:33 +090084 /*
85 * "controller reset" belongs to glue logic, and it should be
86 * accessible in .glue_configure() before access to the controller
87 * begins.
88 */
89 ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
90 name = ofnode_get_name(subnode);
91 if (!strncmp(name, "reset", 5))
92 device_bind_driver_to_node(dev, "uniphier-reset",
93 name, subnode, &child);
94 }
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090095
Kunihiko Hayashic891a462023-02-20 14:50:33 +090096 /* Get controller node that is placed separately from the glue node */
97 *node = ofnode_by_compatible(dev_ofnode(dev->parent),
98 "socionext,uniphier-dwc3");
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090099
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900100 return 0;
101}
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900102
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900103static const struct dwc3_glue_ops uniphier_pro4_dwc3_ops = {
104 .glue_get_ctrl_dev = dwc3_uniphier_glue_get_ctrl_dev,
105 .glue_configure = uniphier_pro4_dwc3_init,
106};
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900107
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900108static const struct dwc3_glue_ops uniphier_pro5_dwc3_ops = {
109 .glue_get_ctrl_dev = dwc3_uniphier_glue_get_ctrl_dev,
110 .glue_configure = uniphier_pro5_dwc3_init,
111};
112
113static const struct dwc3_glue_ops uniphier_pxs2_dwc3_ops = {
114 .glue_get_ctrl_dev = dwc3_uniphier_glue_get_ctrl_dev,
115 .glue_configure = uniphier_pxs2_dwc3_init,
116};
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900117
118static const struct udevice_id uniphier_dwc3_match[] = {
119 {
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900120 .compatible = "socionext,uniphier-pro4-dwc3-glue",
121 .data = (ulong)&uniphier_pro4_dwc3_ops,
122 },
123 {
124 .compatible = "socionext,uniphier-pro5-dwc3-glue",
125 .data = (ulong)&uniphier_pro5_dwc3_ops,
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900126 },
127 {
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900128 .compatible = "socionext,uniphier-pxs2-dwc3-glue",
129 .data = (ulong)&uniphier_pxs2_dwc3_ops,
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900130 },
131 {
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900132 .compatible = "socionext,uniphier-ld20-dwc3-glue",
133 .data = (ulong)&uniphier_pxs2_dwc3_ops,
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900134 },
135 {
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900136 .compatible = "socionext,uniphier-pxs3-dwc3-glue",
137 .data = (ulong)&uniphier_pxs2_dwc3_ops,
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900138 },
139 {
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900140 .compatible = "socionext,uniphier-nx1-dwc3-glue",
141 .data = (ulong)&uniphier_pxs2_dwc3_ops,
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900142 },
143 { /* sentinel */ }
144};
145
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900146U_BOOT_DRIVER(dwc3_uniphier_wrapper) = {
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900147 .name = "uniphier-dwc3",
148 .id = UCLASS_SIMPLE_BUS,
149 .of_match = uniphier_dwc3_match,
Kunihiko Hayashic891a462023-02-20 14:50:33 +0900150 .bind = dwc3_glue_bind,
151 .probe = dwc3_glue_probe,
152 .remove = dwc3_glue_remove,
153 .plat_auto = sizeof(struct dwc3_glue_data),
Masahiro Yamadaa50bab32017-09-28 22:01:00 +0900154};