Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright (C) 2017 John Crispin <john@phrozen.org>
  4 *
  5 * Based on code from
  6 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  7 */
  8
  9#include <linux/delay.h>
 10#include <linux/err.h>
 11#include <linux/io.h>
 12#include <linux/kernel.h>
 13#include <linux/mfd/syscon.h>
 14#include <linux/module.h>
 15#include <linux/mutex.h>
 16#include <linux/of_platform.h>
 17#include <linux/phy/phy.h>
 18#include <linux/platform_device.h>
 19#include <linux/regmap.h>
 20#include <linux/reset.h>
 21
 22#define RT_SYSC_REG_SYSCFG1		0x014
 23#define RT_SYSC_REG_CLKCFG1		0x030
 24#define RT_SYSC_REG_USB_PHY_CFG		0x05c
 25
 26#define OFS_U2_PHY_AC0			0x800
 27#define OFS_U2_PHY_AC1			0x804
 28#define OFS_U2_PHY_AC2			0x808
 29#define OFS_U2_PHY_ACR0			0x810
 30#define OFS_U2_PHY_ACR1			0x814
 31#define OFS_U2_PHY_ACR2			0x818
 32#define OFS_U2_PHY_ACR3			0x81C
 33#define OFS_U2_PHY_ACR4			0x820
 34#define OFS_U2_PHY_AMON0		0x824
 35#define OFS_U2_PHY_DCR0			0x860
 36#define OFS_U2_PHY_DCR1			0x864
 37#define OFS_U2_PHY_DTM0			0x868
 38#define OFS_U2_PHY_DTM1			0x86C
 39
 40#define RT_RSTCTRL_UDEV			BIT(25)
 41#define RT_RSTCTRL_UHST			BIT(22)
 42#define RT_SYSCFG1_USB0_HOST_MODE	BIT(10)
 43
 44#define MT7620_CLKCFG1_UPHY0_CLK_EN	BIT(25)
 45#define MT7620_CLKCFG1_UPHY1_CLK_EN	BIT(22)
 46#define RT_CLKCFG1_UPHY1_CLK_EN		BIT(20)
 47#define RT_CLKCFG1_UPHY0_CLK_EN		BIT(18)
 48
 49#define USB_PHY_UTMI_8B60M		BIT(1)
 50#define UDEV_WAKEUP			BIT(0)
 51
 52struct ralink_usb_phy {
 53	struct reset_control	*rstdev;
 54	struct reset_control	*rsthost;
 55	u32			clk;
 56	struct phy		*phy;
 57	void __iomem		*base;
 58	struct regmap		*sysctl;
 59};
 60
 61static void u2_phy_w32(struct ralink_usb_phy *phy, u32 val, u32 reg)
 62{
 63	writel(val, phy->base + reg);
 64}
 65
 66static u32 u2_phy_r32(struct ralink_usb_phy *phy, u32 reg)
 67{
 68	return readl(phy->base + reg);
 69}
 70
 71static void ralink_usb_phy_init(struct ralink_usb_phy *phy)
 72{
 73	u2_phy_r32(phy, OFS_U2_PHY_AC2);
 74	u2_phy_r32(phy, OFS_U2_PHY_ACR0);
 75	u2_phy_r32(phy, OFS_U2_PHY_DCR0);
 76
 77	u2_phy_w32(phy, 0x00ffff02, OFS_U2_PHY_DCR0);
 78	u2_phy_r32(phy, OFS_U2_PHY_DCR0);
 79	u2_phy_w32(phy, 0x00555502, OFS_U2_PHY_DCR0);
 80	u2_phy_r32(phy, OFS_U2_PHY_DCR0);
 81	u2_phy_w32(phy, 0x00aaaa02, OFS_U2_PHY_DCR0);
 82	u2_phy_r32(phy, OFS_U2_PHY_DCR0);
 83	u2_phy_w32(phy, 0x00000402, OFS_U2_PHY_DCR0);
 84	u2_phy_r32(phy, OFS_U2_PHY_DCR0);
 85	u2_phy_w32(phy, 0x0048086a, OFS_U2_PHY_AC0);
 86	u2_phy_w32(phy, 0x4400001c, OFS_U2_PHY_AC1);
 87	u2_phy_w32(phy, 0xc0200000, OFS_U2_PHY_ACR3);
 88	u2_phy_w32(phy, 0x02000000, OFS_U2_PHY_DTM0);
 89}
 90
 91static int ralink_usb_phy_power_on(struct phy *_phy)
 92{
 93	struct ralink_usb_phy *phy = phy_get_drvdata(_phy);
 94	u32 t;
 95
 96	/* enable the phy */
 97	regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
 98			   phy->clk, phy->clk);
 99
100	/* setup host mode */
101	regmap_update_bits(phy->sysctl, RT_SYSC_REG_SYSCFG1,
102			   RT_SYSCFG1_USB0_HOST_MODE,
103			   RT_SYSCFG1_USB0_HOST_MODE);
104
105	/* deassert the reset lines */
106	reset_control_deassert(phy->rsthost);
107	reset_control_deassert(phy->rstdev);
108
109	/*
110	 * The SDK kernel had a delay of 100ms. however on device
111	 * testing showed that 10ms is enough
112	 */
113	mdelay(10);
114
115	if (phy->base)
116		ralink_usb_phy_init(phy);
117
118	/* print some status info */
119	regmap_read(phy->sysctl, RT_SYSC_REG_USB_PHY_CFG, &t);
120	dev_info(&phy->phy->dev, "remote usb device wakeup %s\n",
121		(t & UDEV_WAKEUP) ? ("enabled") : ("disabled"));
122	if (t & USB_PHY_UTMI_8B60M)
123		dev_info(&phy->phy->dev, "UTMI 8bit 60MHz\n");
124	else
125		dev_info(&phy->phy->dev, "UTMI 16bit 30MHz\n");
126
127	return 0;
128}
129
130static int ralink_usb_phy_power_off(struct phy *_phy)
131{
132	struct ralink_usb_phy *phy = phy_get_drvdata(_phy);
133
134	/* disable the phy */
135	regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
136			   phy->clk, 0);
137
138	/* assert the reset lines */
139	reset_control_assert(phy->rstdev);
140	reset_control_assert(phy->rsthost);
141
142	return 0;
143}
144
145static struct phy_ops ralink_usb_phy_ops = {
146	.power_on	= ralink_usb_phy_power_on,
147	.power_off	= ralink_usb_phy_power_off,
148	.owner		= THIS_MODULE,
149};
150
151static const struct of_device_id ralink_usb_phy_of_match[] = {
152	{
153		.compatible = "ralink,rt3352-usbphy",
154		.data = (void *)(uintptr_t)(RT_CLKCFG1_UPHY1_CLK_EN |
155					    RT_CLKCFG1_UPHY0_CLK_EN)
156	},
157	{
158		.compatible = "mediatek,mt7620-usbphy",
159		.data = (void *)(uintptr_t)(MT7620_CLKCFG1_UPHY1_CLK_EN |
160					    MT7620_CLKCFG1_UPHY0_CLK_EN)
161	},
162	{
163		.compatible = "mediatek,mt7628-usbphy",
164		.data = (void *)(uintptr_t)(MT7620_CLKCFG1_UPHY1_CLK_EN |
165					    MT7620_CLKCFG1_UPHY0_CLK_EN) },
166	{ },
167};
168MODULE_DEVICE_TABLE(of, ralink_usb_phy_of_match);
169
170static int ralink_usb_phy_probe(struct platform_device *pdev)
171{
172	struct device *dev = &pdev->dev;
173	struct resource *res;
174	struct phy_provider *phy_provider;
175	const struct of_device_id *match;
176	struct ralink_usb_phy *phy;
177
178	match = of_match_device(ralink_usb_phy_of_match, &pdev->dev);
179	if (!match)
180		return -ENODEV;
181
182	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
183	if (!phy)
184		return -ENOMEM;
185
186	phy->clk = (uintptr_t)match->data;
187	phy->base = NULL;
188
189	phy->sysctl = syscon_regmap_lookup_by_phandle(dev->of_node, "ralink,sysctl");
190	if (IS_ERR(phy->sysctl)) {
191		dev_err(dev, "failed to get sysctl registers\n");
192		return PTR_ERR(phy->sysctl);
193	}
194
195	/* The MT7628 and MT7688 require extra setup of PHY registers. */
196	if (of_device_is_compatible(dev->of_node, "mediatek,mt7628-usbphy")) {
197		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
198		phy->base = devm_ioremap_resource(&pdev->dev, res);
199		if (IS_ERR(phy->base)) {
200			dev_err(dev, "failed to remap register memory\n");
201			return PTR_ERR(phy->base);
202		}
203	}
204
205	phy->rsthost = devm_reset_control_get(&pdev->dev, "host");
206	if (IS_ERR(phy->rsthost)) {
207		dev_err(dev, "host reset is missing\n");
208		return PTR_ERR(phy->rsthost);
209	}
210
211	phy->rstdev = devm_reset_control_get(&pdev->dev, "device");
212	if (IS_ERR(phy->rstdev)) {
213		dev_err(dev, "device reset is missing\n");
214		return PTR_ERR(phy->rstdev);
215	}
216
217	phy->phy = devm_phy_create(dev, NULL, &ralink_usb_phy_ops);
218	if (IS_ERR(phy->phy)) {
219		dev_err(dev, "failed to create PHY\n");
220		return PTR_ERR(phy->phy);
221	}
222	phy_set_drvdata(phy->phy, phy);
223
224	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
225
226	return PTR_ERR_OR_ZERO(phy_provider);
227}
228
229static struct platform_driver ralink_usb_phy_driver = {
230	.probe	= ralink_usb_phy_probe,
231	.driver = {
232		.of_match_table	= ralink_usb_phy_of_match,
233		.name  = "ralink-usb-phy",
234	}
235};
236module_platform_driver(ralink_usb_phy_driver);
237
238MODULE_DESCRIPTION("Ralink USB phy driver");
239MODULE_AUTHOR("John Crispin <john@phrozen.org>");
240MODULE_LICENSE("GPL v2");