Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  1/*
  2 * phy-ti-pipe3 - PIPE3 PHY driver.
  3 *
  4 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
  5 * This program is free software; you can redistribute it and/or modify
  6 * it under the terms of the GNU General Public License as published by
  7 * the Free Software Foundation; either version 2 of the License, or
  8 * (at your option) any later version.
  9 *
 10 * Author: Kishon Vijay Abraham I <kishon@ti.com>
 11 *
 12 * This program is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15 * GNU General Public License for more details.
 16 *
 17 */
 18
 19#include <linux/module.h>
 20#include <linux/platform_device.h>
 21#include <linux/slab.h>
 22#include <linux/phy/phy.h>
 23#include <linux/of.h>
 24#include <linux/clk.h>
 25#include <linux/err.h>
 26#include <linux/io.h>
 27#include <linux/pm_runtime.h>
 28#include <linux/delay.h>
 29#include <linux/phy/omap_control_phy.h>
 30#include <linux/of_platform.h>
 31
 32#define	PLL_STATUS		0x00000004
 33#define	PLL_GO			0x00000008
 34#define	PLL_CONFIGURATION1	0x0000000C
 35#define	PLL_CONFIGURATION2	0x00000010
 36#define	PLL_CONFIGURATION3	0x00000014
 37#define	PLL_CONFIGURATION4	0x00000020
 38
 39#define	PLL_REGM_MASK		0x001FFE00
 40#define	PLL_REGM_SHIFT		0x9
 41#define	PLL_REGM_F_MASK		0x0003FFFF
 42#define	PLL_REGM_F_SHIFT	0x0
 43#define	PLL_REGN_MASK		0x000001FE
 44#define	PLL_REGN_SHIFT		0x1
 45#define	PLL_SELFREQDCO_MASK	0x0000000E
 46#define	PLL_SELFREQDCO_SHIFT	0x1
 47#define	PLL_SD_MASK		0x0003FC00
 48#define	PLL_SD_SHIFT		10
 49#define	SET_PLL_GO		0x1
 50#define PLL_LDOPWDN		BIT(15)
 51#define PLL_TICOPWDN		BIT(16)
 52#define	PLL_LOCK		0x2
 53#define	PLL_IDLE		0x1
 54
 55/*
 56 * This is an Empirical value that works, need to confirm the actual
 57 * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
 58 * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
 59 */
 60#define PLL_IDLE_TIME	100	/* in milliseconds */
 61#define PLL_LOCK_TIME	100	/* in milliseconds */
 62
 63struct pipe3_dpll_params {
 64	u16	m;
 65	u8	n;
 66	u8	freq:3;
 67	u8	sd;
 68	u32	mf;
 69};
 70
 71struct pipe3_dpll_map {
 72	unsigned long rate;
 73	struct pipe3_dpll_params params;
 74};
 75
 76struct ti_pipe3 {
 77	void __iomem		*pll_ctrl_base;
 78	struct device		*dev;
 79	struct device		*control_dev;
 80	struct clk		*wkupclk;
 81	struct clk		*sys_clk;
 82	struct clk		*refclk;
 83	struct pipe3_dpll_map	*dpll_map;
 84};
 85
 86static struct pipe3_dpll_map dpll_map_usb[] = {
 87	{12000000, {1250, 5, 4, 20, 0} },	/* 12 MHz */
 88	{16800000, {3125, 20, 4, 20, 0} },	/* 16.8 MHz */
 89	{19200000, {1172, 8, 4, 20, 65537} },	/* 19.2 MHz */
 90	{20000000, {1000, 7, 4, 10, 0} },	/* 20 MHz */
 91	{26000000, {1250, 12, 4, 20, 0} },	/* 26 MHz */
 92	{38400000, {3125, 47, 4, 20, 92843} },	/* 38.4 MHz */
 93	{ },					/* Terminator */
 94};
 95
 96static struct pipe3_dpll_map dpll_map_sata[] = {
 97	{12000000, {1000, 7, 4, 6, 0} },	/* 12 MHz */
 98	{16800000, {714, 7, 4, 6, 0} },		/* 16.8 MHz */
 99	{19200000, {625, 7, 4, 6, 0} },		/* 19.2 MHz */
100	{20000000, {600, 7, 4, 6, 0} },		/* 20 MHz */
101	{26000000, {461, 7, 4, 6, 0} },		/* 26 MHz */
102	{38400000, {312, 7, 4, 6, 0} },		/* 38.4 MHz */
103	{ },					/* Terminator */
104};
105
106static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset)
107{
108	return __raw_readl(addr + offset);
109}
110
111static inline void ti_pipe3_writel(void __iomem *addr, unsigned offset,
112	u32 data)
113{
114	__raw_writel(data, addr + offset);
115}
116
117static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(struct ti_pipe3 *phy)
118{
119	unsigned long rate;
120	struct pipe3_dpll_map *dpll_map = phy->dpll_map;
121
122	rate = clk_get_rate(phy->sys_clk);
123
124	for (; dpll_map->rate; dpll_map++) {
125		if (rate == dpll_map->rate)
126			return &dpll_map->params;
127	}
128
129	dev_err(phy->dev, "No DPLL configuration for %lu Hz SYS CLK\n", rate);
130
131	return NULL;
132}
133
134static int ti_pipe3_power_off(struct phy *x)
135{
136	struct ti_pipe3 *phy = phy_get_drvdata(x);
137
138	omap_control_phy_power(phy->control_dev, 0);
139
140	return 0;
141}
142
143static int ti_pipe3_power_on(struct phy *x)
144{
145	struct ti_pipe3 *phy = phy_get_drvdata(x);
146
147	omap_control_phy_power(phy->control_dev, 1);
148
149	return 0;
150}
151
152static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy)
153{
154	u32		val;
155	unsigned long	timeout;
156
157	timeout = jiffies + msecs_to_jiffies(PLL_LOCK_TIME);
158	do {
159		cpu_relax();
160		val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
161		if (val & PLL_LOCK)
162			break;
163	} while (!time_after(jiffies, timeout));
164
165	if (!(val & PLL_LOCK)) {
166		dev_err(phy->dev, "DPLL failed to lock\n");
167		return -EBUSY;
168	}
169
170	return 0;
171}
172
173static int ti_pipe3_dpll_program(struct ti_pipe3 *phy)
174{
175	u32			val;
176	struct pipe3_dpll_params *dpll_params;
177
178	dpll_params = ti_pipe3_get_dpll_params(phy);
179	if (!dpll_params)
180		return -EINVAL;
181
182	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
183	val &= ~PLL_REGN_MASK;
184	val |= dpll_params->n << PLL_REGN_SHIFT;
185	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
186
187	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
188	val &= ~PLL_SELFREQDCO_MASK;
189	val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
190	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
191
192	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
193	val &= ~PLL_REGM_MASK;
194	val |= dpll_params->m << PLL_REGM_SHIFT;
195	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
196
197	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
198	val &= ~PLL_REGM_F_MASK;
199	val |= dpll_params->mf << PLL_REGM_F_SHIFT;
200	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
201
202	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
203	val &= ~PLL_SD_MASK;
204	val |= dpll_params->sd << PLL_SD_SHIFT;
205	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
206
207	ti_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
208
209	return ti_pipe3_dpll_wait_lock(phy);
210}
211
212static int ti_pipe3_init(struct phy *x)
213{
214	struct ti_pipe3 *phy = phy_get_drvdata(x);
215	u32 val;
216	int ret = 0;
217
218	/* Bring it out of IDLE if it is IDLE */
219	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
220	if (val & PLL_IDLE) {
221		val &= ~PLL_IDLE;
222		ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
223		ret = ti_pipe3_dpll_wait_lock(phy);
224	}
225
226	/* Program the DPLL only if not locked */
227	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
228	if (!(val & PLL_LOCK))
229		if (ti_pipe3_dpll_program(phy))
230			return -EINVAL;
231
232	return ret;
233}
234
235static int ti_pipe3_exit(struct phy *x)
236{
237	struct ti_pipe3 *phy = phy_get_drvdata(x);
238	u32 val;
239	unsigned long timeout;
240
241	/* SATA DPLL can't be powered down due to Errata i783 */
242	if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata"))
243		return 0;
244
245	/* Put DPLL in IDLE mode */
246	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
247	val |= PLL_IDLE;
248	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
249
250	/* wait for LDO and Oscillator to power down */
251	timeout = jiffies + msecs_to_jiffies(PLL_IDLE_TIME);
252	do {
253		cpu_relax();
254		val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
255		if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN))
256			break;
257	} while (!time_after(jiffies, timeout));
258
259	if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) {
260		dev_err(phy->dev, "Failed to power down: PLL_STATUS 0x%x\n",
261			val);
262		return -EBUSY;
263	}
264
265	return 0;
266}
267static struct phy_ops ops = {
268	.init		= ti_pipe3_init,
269	.exit		= ti_pipe3_exit,
270	.power_on	= ti_pipe3_power_on,
271	.power_off	= ti_pipe3_power_off,
272	.owner		= THIS_MODULE,
273};
274
275#ifdef CONFIG_OF
276static const struct of_device_id ti_pipe3_id_table[];
277#endif
278
279static int ti_pipe3_probe(struct platform_device *pdev)
280{
281	struct ti_pipe3 *phy;
282	struct phy *generic_phy;
283	struct phy_provider *phy_provider;
284	struct resource *res;
285	struct device_node *node = pdev->dev.of_node;
286	struct device_node *control_node;
287	struct platform_device *control_pdev;
288	const struct of_device_id *match;
289
290	match = of_match_device(of_match_ptr(ti_pipe3_id_table), &pdev->dev);
291	if (!match)
292		return -EINVAL;
293
294	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
295	if (!phy) {
296		dev_err(&pdev->dev, "unable to alloc mem for TI PIPE3 PHY\n");
297		return -ENOMEM;
298	}
299
300	phy->dpll_map = (struct pipe3_dpll_map *)match->data;
301	if (!phy->dpll_map) {
302		dev_err(&pdev->dev, "no DPLL data\n");
303		return -EINVAL;
304	}
305
306	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
307	phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
308	if (IS_ERR(phy->pll_ctrl_base))
309		return PTR_ERR(phy->pll_ctrl_base);
310
311	phy->dev		= &pdev->dev;
312
313	if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) {
314
315		phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
316		if (IS_ERR(phy->wkupclk)) {
317			dev_err(&pdev->dev, "unable to get wkupclk\n");
318			return PTR_ERR(phy->wkupclk);
319		}
320
321		phy->refclk = devm_clk_get(phy->dev, "refclk");
322		if (IS_ERR(phy->refclk)) {
323			dev_err(&pdev->dev, "unable to get refclk\n");
324			return PTR_ERR(phy->refclk);
325		}
326	} else {
327		phy->wkupclk = ERR_PTR(-ENODEV);
328		phy->refclk = ERR_PTR(-ENODEV);
329	}
330
331	phy->sys_clk = devm_clk_get(phy->dev, "sysclk");
332	if (IS_ERR(phy->sys_clk)) {
333		dev_err(&pdev->dev, "unable to get sysclk\n");
334		return -EINVAL;
335	}
336
337	control_node = of_parse_phandle(node, "ctrl-module", 0);
338	if (!control_node) {
339		dev_err(&pdev->dev, "Failed to get control device phandle\n");
340		return -EINVAL;
341	}
342
343	control_pdev = of_find_device_by_node(control_node);
344	if (!control_pdev) {
345		dev_err(&pdev->dev, "Failed to get control device\n");
346		return -EINVAL;
347	}
348
349	phy->control_dev = &control_pdev->dev;
350
351	omap_control_phy_power(phy->control_dev, 0);
352
353	platform_set_drvdata(pdev, phy);
354	pm_runtime_enable(phy->dev);
355
356	generic_phy = devm_phy_create(phy->dev, &ops, NULL);
357	if (IS_ERR(generic_phy))
358		return PTR_ERR(generic_phy);
359
360	phy_set_drvdata(generic_phy, phy);
361	phy_provider = devm_of_phy_provider_register(phy->dev,
362			of_phy_simple_xlate);
363	if (IS_ERR(phy_provider))
364		return PTR_ERR(phy_provider);
365
366	pm_runtime_get(&pdev->dev);
367
368	return 0;
369}
370
371static int ti_pipe3_remove(struct platform_device *pdev)
372{
373	if (!pm_runtime_suspended(&pdev->dev))
374		pm_runtime_put(&pdev->dev);
375	pm_runtime_disable(&pdev->dev);
376
377	return 0;
378}
379
380#ifdef CONFIG_PM_RUNTIME
381
382static int ti_pipe3_runtime_suspend(struct device *dev)
383{
384	struct ti_pipe3	*phy = dev_get_drvdata(dev);
385
386	if (!IS_ERR(phy->wkupclk))
387		clk_disable_unprepare(phy->wkupclk);
388	if (!IS_ERR(phy->refclk))
389		clk_disable_unprepare(phy->refclk);
390
391	return 0;
392}
393
394static int ti_pipe3_runtime_resume(struct device *dev)
395{
396	u32 ret = 0;
397	struct ti_pipe3	*phy = dev_get_drvdata(dev);
398
399	if (!IS_ERR(phy->refclk)) {
400		ret = clk_prepare_enable(phy->refclk);
401		if (ret) {
402			dev_err(phy->dev, "Failed to enable refclk %d\n", ret);
403			goto err1;
404		}
405	}
406
407	if (!IS_ERR(phy->wkupclk)) {
408		ret = clk_prepare_enable(phy->wkupclk);
409		if (ret) {
410			dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
411			goto err2;
412		}
413	}
414
415	return 0;
416
417err2:
418	if (!IS_ERR(phy->refclk))
419		clk_disable_unprepare(phy->refclk);
420
421err1:
422	return ret;
423}
424
425static const struct dev_pm_ops ti_pipe3_pm_ops = {
426	SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend,
427			   ti_pipe3_runtime_resume, NULL)
428};
429
430#define DEV_PM_OPS     (&ti_pipe3_pm_ops)
431#else
432#define DEV_PM_OPS     NULL
433#endif
434
435#ifdef CONFIG_OF
436static const struct of_device_id ti_pipe3_id_table[] = {
437	{
438		.compatible = "ti,phy-usb3",
439		.data = dpll_map_usb,
440	},
441	{
442		.compatible = "ti,omap-usb3",
443		.data = dpll_map_usb,
444	},
445	{
446		.compatible = "ti,phy-pipe3-sata",
447		.data = dpll_map_sata,
448	},
449	{}
450};
451MODULE_DEVICE_TABLE(of, ti_pipe3_id_table);
452#endif
453
454static struct platform_driver ti_pipe3_driver = {
455	.probe		= ti_pipe3_probe,
456	.remove		= ti_pipe3_remove,
457	.driver		= {
458		.name	= "ti-pipe3",
459		.owner	= THIS_MODULE,
460		.pm	= DEV_PM_OPS,
461		.of_match_table = of_match_ptr(ti_pipe3_id_table),
462	},
463};
464
465module_platform_driver(ti_pipe3_driver);
466
467MODULE_ALIAS("platform: ti_pipe3");
468MODULE_AUTHOR("Texas Instruments Inc.");
469MODULE_DESCRIPTION("TI PIPE3 phy driver");
470MODULE_LICENSE("GPL v2");