xref: /OK3568_Linux_fs/u-boot/drivers/usb/dwc3/dwc3-uniphier.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * UniPhier Specific Glue Layer for DWC3
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2016-2017 Socionext Inc.
5*4882a593Smuzhiyun  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <dm.h>
11*4882a593Smuzhiyun #include <linux/bitops.h>
12*4882a593Smuzhiyun #include <linux/errno.h>
13*4882a593Smuzhiyun #include <linux/io.h>
14*4882a593Smuzhiyun #include <linux/sizes.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define UNIPHIER_PRO4_DWC3_RESET	0x40
17*4882a593Smuzhiyun #define   UNIPHIER_PRO4_DWC3_RESET_XIOMMU	BIT(5)
18*4882a593Smuzhiyun #define   UNIPHIER_PRO4_DWC3_RESET_XLINK	BIT(4)
19*4882a593Smuzhiyun #define   UNIPHIER_PRO4_DWC3_RESET_PHY_SS	BIT(2)
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #define UNIPHIER_PRO5_DWC3_RESET	0x00
22*4882a593Smuzhiyun #define   UNIPHIER_PRO5_DWC3_RESET_PHY_S1	BIT(17)
23*4882a593Smuzhiyun #define   UNIPHIER_PRO5_DWC3_RESET_PHY_S0	BIT(16)
24*4882a593Smuzhiyun #define   UNIPHIER_PRO5_DWC3_RESET_XLINK	BIT(15)
25*4882a593Smuzhiyun #define   UNIPHIER_PRO5_DWC3_RESET_XIOMMU	BIT(14)
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define UNIPHIER_PXS2_DWC3_RESET	0x00
28*4882a593Smuzhiyun #define   UNIPHIER_PXS2_DWC3_RESET_XLINK	BIT(15)
29*4882a593Smuzhiyun 
uniphier_pro4_dwc3_init(void __iomem * regs)30*4882a593Smuzhiyun static int uniphier_pro4_dwc3_init(void __iomem *regs)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun 	u32 tmp;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
35*4882a593Smuzhiyun 	tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS;
36*4882a593Smuzhiyun 	tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
37*4882a593Smuzhiyun 	writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	return 0;
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun 
uniphier_pro5_dwc3_init(void __iomem * regs)42*4882a593Smuzhiyun static int uniphier_pro5_dwc3_init(void __iomem *regs)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun 	u32 tmp;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET);
47*4882a593Smuzhiyun 	tmp &= ~(UNIPHIER_PRO5_DWC3_RESET_PHY_S1 |
48*4882a593Smuzhiyun 		 UNIPHIER_PRO5_DWC3_RESET_PHY_S0);
49*4882a593Smuzhiyun 	tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU;
50*4882a593Smuzhiyun 	writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	return 0;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
uniphier_pxs2_dwc3_init(void __iomem * regs)55*4882a593Smuzhiyun static int uniphier_pxs2_dwc3_init(void __iomem *regs)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	u32 tmp;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET);
60*4882a593Smuzhiyun 	tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK;
61*4882a593Smuzhiyun 	writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET);
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	return 0;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
uniphier_dwc3_probe(struct udevice * dev)66*4882a593Smuzhiyun static int uniphier_dwc3_probe(struct udevice *dev)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	fdt_addr_t base;
69*4882a593Smuzhiyun 	void __iomem *regs;
70*4882a593Smuzhiyun 	int (*init)(void __iomem *regs);
71*4882a593Smuzhiyun 	int ret;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	base = devfdt_get_addr(dev);
74*4882a593Smuzhiyun 	if (base == FDT_ADDR_T_NONE)
75*4882a593Smuzhiyun 		return -EINVAL;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	regs = ioremap(base, SZ_32K);
78*4882a593Smuzhiyun 	if (!regs)
79*4882a593Smuzhiyun 		return -ENOMEM;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	init = (typeof(init))dev_get_driver_data(dev);
82*4882a593Smuzhiyun 	ret = init(regs);
83*4882a593Smuzhiyun 	if (ret)
84*4882a593Smuzhiyun 		dev_err(dev, "failed to init glue layer\n");
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	iounmap(regs);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	return ret;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun static const struct udevice_id uniphier_dwc3_match[] = {
92*4882a593Smuzhiyun 	{
93*4882a593Smuzhiyun 		.compatible = "socionext,uniphier-pro4-dwc3",
94*4882a593Smuzhiyun 		.data = (ulong)uniphier_pro4_dwc3_init,
95*4882a593Smuzhiyun 	},
96*4882a593Smuzhiyun 	{
97*4882a593Smuzhiyun 		.compatible = "socionext,uniphier-pro5-dwc3",
98*4882a593Smuzhiyun 		.data = (ulong)uniphier_pro5_dwc3_init,
99*4882a593Smuzhiyun 	},
100*4882a593Smuzhiyun 	{
101*4882a593Smuzhiyun 		.compatible = "socionext,uniphier-pxs2-dwc3",
102*4882a593Smuzhiyun 		.data = (ulong)uniphier_pxs2_dwc3_init,
103*4882a593Smuzhiyun 	},
104*4882a593Smuzhiyun 	{
105*4882a593Smuzhiyun 		.compatible = "socionext,uniphier-ld20-dwc3",
106*4882a593Smuzhiyun 		.data = (ulong)uniphier_pxs2_dwc3_init,
107*4882a593Smuzhiyun 	},
108*4882a593Smuzhiyun 	{
109*4882a593Smuzhiyun 		.compatible = "socionext,uniphier-pxs3-dwc3",
110*4882a593Smuzhiyun 		.data = (ulong)uniphier_pxs2_dwc3_init,
111*4882a593Smuzhiyun 	},
112*4882a593Smuzhiyun 	{ /* sentinel */ }
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun U_BOOT_DRIVER(usb_xhci) = {
116*4882a593Smuzhiyun 	.name = "uniphier-dwc3",
117*4882a593Smuzhiyun 	.id = UCLASS_SIMPLE_BUS,
118*4882a593Smuzhiyun 	.of_match = uniphier_dwc3_match,
119*4882a593Smuzhiyun 	.probe = uniphier_dwc3_probe,
120*4882a593Smuzhiyun };
121