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#include <linux/mfd/syscon.h>
 32#include <linux/regmap.h>
 33
 34#define	PLL_STATUS		0x00000004
 35#define	PLL_GO			0x00000008
 36#define	PLL_CONFIGURATION1	0x0000000C
 37#define	PLL_CONFIGURATION2	0x00000010
 38#define	PLL_CONFIGURATION3	0x00000014
 39#define	PLL_CONFIGURATION4	0x00000020
 40
 41#define	PLL_REGM_MASK		0x001FFE00
 42#define	PLL_REGM_SHIFT		0x9
 43#define	PLL_REGM_F_MASK		0x0003FFFF
 44#define	PLL_REGM_F_SHIFT	0x0
 45#define	PLL_REGN_MASK		0x000001FE
 46#define	PLL_REGN_SHIFT		0x1
 47#define	PLL_SELFREQDCO_MASK	0x0000000E
 48#define	PLL_SELFREQDCO_SHIFT	0x1
 49#define	PLL_SD_MASK		0x0003FC00
 50#define	PLL_SD_SHIFT		10
 51#define	SET_PLL_GO		0x1
 52#define PLL_LDOPWDN		BIT(15)
 53#define PLL_TICOPWDN		BIT(16)
 54#define	PLL_LOCK		0x2
 55#define	PLL_IDLE		0x1
 56
 57#define SATA_PLL_SOFT_RESET	BIT(18)
 58
 59#define PIPE3_PHY_PWRCTL_CLK_CMD_MASK	0x003FC000
 60#define PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT	14
 61
 62#define PIPE3_PHY_PWRCTL_CLK_FREQ_MASK	0xFFC00000
 63#define PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT	22
 64
 65#define PIPE3_PHY_TX_RX_POWERON		0x3
 66#define PIPE3_PHY_TX_RX_POWEROFF	0x0
 67
 68#define PCIE_PCS_MASK			0xFF0000
 69#define PCIE_PCS_DELAY_COUNT_SHIFT	0x10
 70
 71/*
 72 * This is an Empirical value that works, need to confirm the actual
 73 * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
 74 * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
 75 */
 76#define PLL_IDLE_TIME	100	/* in milliseconds */
 77#define PLL_LOCK_TIME	100	/* in milliseconds */
 78
 79struct pipe3_dpll_params {
 80	u16	m;
 81	u8	n;
 82	u8	freq:3;
 83	u8	sd;
 84	u32	mf;
 85};
 86
 87struct pipe3_dpll_map {
 88	unsigned long rate;
 89	struct pipe3_dpll_params params;
 90};
 91
 92struct ti_pipe3 {
 93	void __iomem		*pll_ctrl_base;
 94	struct device		*dev;
 95	struct device		*control_dev;
 96	struct clk		*wkupclk;
 97	struct clk		*sys_clk;
 98	struct clk		*refclk;
 99	struct clk		*div_clk;
100	struct pipe3_dpll_map	*dpll_map;
101	struct regmap		*phy_power_syscon; /* ctrl. reg. acces */
102	struct regmap		*pcs_syscon; /* ctrl. reg. acces */
103	struct regmap		*dpll_reset_syscon; /* ctrl. reg. acces */
104	unsigned int		dpll_reset_reg; /* reg. index within syscon */
105	unsigned int		power_reg; /* power reg. index within syscon */
106	unsigned int		pcie_pcs_reg; /* pcs reg. index in syscon */
107	bool			sata_refclk_enabled;
108};
109
110static struct pipe3_dpll_map dpll_map_usb[] = {
111	{12000000, {1250, 5, 4, 20, 0} },	/* 12 MHz */
112	{16800000, {3125, 20, 4, 20, 0} },	/* 16.8 MHz */
113	{19200000, {1172, 8, 4, 20, 65537} },	/* 19.2 MHz */
114	{20000000, {1000, 7, 4, 10, 0} },	/* 20 MHz */
115	{26000000, {1250, 12, 4, 20, 0} },	/* 26 MHz */
116	{38400000, {3125, 47, 4, 20, 92843} },	/* 38.4 MHz */
117	{ },					/* Terminator */
118};
119
120static struct pipe3_dpll_map dpll_map_sata[] = {
121	{12000000, {1000, 7, 4, 6, 0} },	/* 12 MHz */
122	{16800000, {714, 7, 4, 6, 0} },		/* 16.8 MHz */
123	{19200000, {625, 7, 4, 6, 0} },		/* 19.2 MHz */
124	{20000000, {600, 7, 4, 6, 0} },		/* 20 MHz */
125	{26000000, {461, 7, 4, 6, 0} },		/* 26 MHz */
126	{38400000, {312, 7, 4, 6, 0} },		/* 38.4 MHz */
127	{ },					/* Terminator */
128};
129
130static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset)
131{
132	return __raw_readl(addr + offset);
133}
134
135static inline void ti_pipe3_writel(void __iomem *addr, unsigned offset,
136	u32 data)
137{
138	__raw_writel(data, addr + offset);
139}
140
141static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(struct ti_pipe3 *phy)
142{
143	unsigned long rate;
144	struct pipe3_dpll_map *dpll_map = phy->dpll_map;
145
146	rate = clk_get_rate(phy->sys_clk);
147
148	for (; dpll_map->rate; dpll_map++) {
149		if (rate == dpll_map->rate)
150			return &dpll_map->params;
151	}
152
153	dev_err(phy->dev, "No DPLL configuration for %lu Hz SYS CLK\n", rate);
154
155	return NULL;
156}
157
158static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy);
159static void ti_pipe3_disable_clocks(struct ti_pipe3 *phy);
160
161static int ti_pipe3_power_off(struct phy *x)
162{
163	u32 val;
164	int ret;
165	struct ti_pipe3 *phy = phy_get_drvdata(x);
166
167	if (!phy->phy_power_syscon) {
168		omap_control_phy_power(phy->control_dev, 0);
169		return 0;
170	}
171
172	val = PIPE3_PHY_TX_RX_POWEROFF << PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT;
173
174	ret = regmap_update_bits(phy->phy_power_syscon, phy->power_reg,
175				 PIPE3_PHY_PWRCTL_CLK_CMD_MASK, val);
176	return ret;
177}
178
179static int ti_pipe3_power_on(struct phy *x)
180{
181	u32 val;
182	u32 mask;
183	int ret;
184	unsigned long rate;
185	struct ti_pipe3 *phy = phy_get_drvdata(x);
186
187	if (!phy->phy_power_syscon) {
188		omap_control_phy_power(phy->control_dev, 1);
189		return 0;
190	}
191
192	rate = clk_get_rate(phy->sys_clk);
193	if (!rate) {
194		dev_err(phy->dev, "Invalid clock rate\n");
195		return -EINVAL;
196	}
197	rate = rate / 1000000;
198	mask = OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK |
199		  OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK;
200	val = PIPE3_PHY_TX_RX_POWERON << PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT;
201	val |= rate << OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT;
202
203	ret = regmap_update_bits(phy->phy_power_syscon, phy->power_reg,
204				 mask, val);
205	return ret;
206}
207
208static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy)
209{
210	u32		val;
211	unsigned long	timeout;
212
213	timeout = jiffies + msecs_to_jiffies(PLL_LOCK_TIME);
214	do {
215		cpu_relax();
216		val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
217		if (val & PLL_LOCK)
218			return 0;
219	} while (!time_after(jiffies, timeout));
220
221	dev_err(phy->dev, "DPLL failed to lock\n");
222	return -EBUSY;
223}
224
225static int ti_pipe3_dpll_program(struct ti_pipe3 *phy)
226{
227	u32			val;
228	struct pipe3_dpll_params *dpll_params;
229
230	dpll_params = ti_pipe3_get_dpll_params(phy);
231	if (!dpll_params)
232		return -EINVAL;
233
234	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
235	val &= ~PLL_REGN_MASK;
236	val |= dpll_params->n << PLL_REGN_SHIFT;
237	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
238
239	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
240	val &= ~PLL_SELFREQDCO_MASK;
241	val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
242	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
243
244	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
245	val &= ~PLL_REGM_MASK;
246	val |= dpll_params->m << PLL_REGM_SHIFT;
247	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
248
249	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
250	val &= ~PLL_REGM_F_MASK;
251	val |= dpll_params->mf << PLL_REGM_F_SHIFT;
252	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
253
254	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
255	val &= ~PLL_SD_MASK;
256	val |= dpll_params->sd << PLL_SD_SHIFT;
257	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
258
259	ti_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
260
261	return ti_pipe3_dpll_wait_lock(phy);
262}
263
264static int ti_pipe3_init(struct phy *x)
265{
266	struct ti_pipe3 *phy = phy_get_drvdata(x);
267	u32 val;
268	int ret = 0;
269
270	ti_pipe3_enable_clocks(phy);
271	/*
272	 * Set pcie_pcs register to 0x96 for proper functioning of phy
273	 * as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table
274	 * 18-1804.
275	 */
276	if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) {
277		if (!phy->pcs_syscon) {
278			omap_control_pcie_pcs(phy->control_dev, 0x96);
279			return 0;
280		}
281
282		val = 0x96 << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT;
283		ret = regmap_update_bits(phy->pcs_syscon, phy->pcie_pcs_reg,
284					 PCIE_PCS_MASK, val);
285		return ret;
286	}
287
288	/* Bring it out of IDLE if it is IDLE */
289	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
290	if (val & PLL_IDLE) {
291		val &= ~PLL_IDLE;
292		ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
293		ret = ti_pipe3_dpll_wait_lock(phy);
294	}
295
296	/* Program the DPLL only if not locked */
297	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
298	if (!(val & PLL_LOCK))
299		if (ti_pipe3_dpll_program(phy))
300			return -EINVAL;
301
302	return ret;
303}
304
305static int ti_pipe3_exit(struct phy *x)
306{
307	struct ti_pipe3 *phy = phy_get_drvdata(x);
308	u32 val;
309	unsigned long timeout;
310
311	/* If dpll_reset_syscon is not present we wont power down SATA DPLL
312	 * due to Errata i783
313	 */
314	if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") &&
315	    !phy->dpll_reset_syscon)
316		return 0;
317
318	/* PCIe doesn't have internal DPLL */
319	if (!of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) {
320		/* Put DPLL in IDLE mode */
321		val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
322		val |= PLL_IDLE;
323		ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
324
325		/* wait for LDO and Oscillator to power down */
326		timeout = jiffies + msecs_to_jiffies(PLL_IDLE_TIME);
327		do {
328			cpu_relax();
329			val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
330			if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN))
331				break;
332		} while (!time_after(jiffies, timeout));
333
334		if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) {
335			dev_err(phy->dev, "Failed to power down: PLL_STATUS 0x%x\n",
336				val);
337			return -EBUSY;
338		}
339	}
340
341	/* i783: SATA needs control bit toggle after PLL unlock */
342	if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata")) {
343		regmap_update_bits(phy->dpll_reset_syscon, phy->dpll_reset_reg,
344				   SATA_PLL_SOFT_RESET, SATA_PLL_SOFT_RESET);
345		regmap_update_bits(phy->dpll_reset_syscon, phy->dpll_reset_reg,
346				   SATA_PLL_SOFT_RESET, 0);
347	}
348
349	ti_pipe3_disable_clocks(phy);
350
351	return 0;
352}
353static const struct phy_ops ops = {
354	.init		= ti_pipe3_init,
355	.exit		= ti_pipe3_exit,
356	.power_on	= ti_pipe3_power_on,
357	.power_off	= ti_pipe3_power_off,
358	.owner		= THIS_MODULE,
359};
360
361static const struct of_device_id ti_pipe3_id_table[];
362
363static int ti_pipe3_get_clk(struct ti_pipe3 *phy)
364{
365	struct clk *clk;
366	struct device *dev = phy->dev;
367	struct device_node *node = dev->of_node;
368
369	phy->refclk = devm_clk_get(dev, "refclk");
370	if (IS_ERR(phy->refclk)) {
371		dev_err(dev, "unable to get refclk\n");
372		/* older DTBs have missing refclk in SATA PHY
373		 * so don't bail out in case of SATA PHY.
374		 */
375		if (!of_device_is_compatible(node, "ti,phy-pipe3-sata"))
376			return PTR_ERR(phy->refclk);
377	}
378
379	if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) {
380		phy->wkupclk = devm_clk_get(dev, "wkupclk");
381		if (IS_ERR(phy->wkupclk)) {
382			dev_err(dev, "unable to get wkupclk\n");
383			return PTR_ERR(phy->wkupclk);
384		}
385	} else {
386		phy->wkupclk = ERR_PTR(-ENODEV);
387	}
388
389	if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie") ||
390	    phy->phy_power_syscon) {
391		phy->sys_clk = devm_clk_get(dev, "sysclk");
392		if (IS_ERR(phy->sys_clk)) {
393			dev_err(dev, "unable to get sysclk\n");
394			return -EINVAL;
395		}
396	}
397
398	if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
399		clk = devm_clk_get(dev, "dpll_ref");
400		if (IS_ERR(clk)) {
401			dev_err(dev, "unable to get dpll ref clk\n");
402			return PTR_ERR(clk);
403		}
404		clk_set_rate(clk, 1500000000);
405
406		clk = devm_clk_get(dev, "dpll_ref_m2");
407		if (IS_ERR(clk)) {
408			dev_err(dev, "unable to get dpll ref m2 clk\n");
409			return PTR_ERR(clk);
410		}
411		clk_set_rate(clk, 100000000);
412
413		clk = devm_clk_get(dev, "phy-div");
414		if (IS_ERR(clk)) {
415			dev_err(dev, "unable to get phy-div clk\n");
416			return PTR_ERR(clk);
417		}
418		clk_set_rate(clk, 100000000);
419
420		phy->div_clk = devm_clk_get(dev, "div-clk");
421		if (IS_ERR(phy->div_clk)) {
422			dev_err(dev, "unable to get div-clk\n");
423			return PTR_ERR(phy->div_clk);
424		}
425	} else {
426		phy->div_clk = ERR_PTR(-ENODEV);
427	}
428
429	return 0;
430}
431
432static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy)
433{
434	struct device *dev = phy->dev;
435	struct device_node *node = dev->of_node;
436	struct device_node *control_node;
437	struct platform_device *control_pdev;
438
439	phy->phy_power_syscon = syscon_regmap_lookup_by_phandle(node,
440							"syscon-phy-power");
441	if (IS_ERR(phy->phy_power_syscon)) {
442		dev_dbg(dev,
443			"can't get syscon-phy-power, using control device\n");
444		phy->phy_power_syscon = NULL;
445	} else {
446		if (of_property_read_u32_index(node,
447					       "syscon-phy-power", 1,
448					       &phy->power_reg)) {
449			dev_err(dev, "couldn't get power reg. offset\n");
450			return -EINVAL;
451		}
452	}
453
454	if (!phy->phy_power_syscon) {
455		control_node = of_parse_phandle(node, "ctrl-module", 0);
456		if (!control_node) {
457			dev_err(dev, "Failed to get control device phandle\n");
458			return -EINVAL;
459		}
460
461		control_pdev = of_find_device_by_node(control_node);
462		if (!control_pdev) {
463			dev_err(dev, "Failed to get control device\n");
464			return -EINVAL;
465		}
466
467		phy->control_dev = &control_pdev->dev;
468	}
469
470	if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
471		phy->pcs_syscon = syscon_regmap_lookup_by_phandle(node,
472								  "syscon-pcs");
473		if (IS_ERR(phy->pcs_syscon)) {
474			dev_dbg(dev,
475				"can't get syscon-pcs, using omap control\n");
476			phy->pcs_syscon = NULL;
477		} else {
478			if (of_property_read_u32_index(node,
479						       "syscon-pcs", 1,
480						       &phy->pcie_pcs_reg)) {
481				dev_err(dev,
482					"couldn't get pcie pcs reg. offset\n");
483				return -EINVAL;
484			}
485		}
486	}
487
488	if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) {
489		phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node,
490							"syscon-pllreset");
491		if (IS_ERR(phy->dpll_reset_syscon)) {
492			dev_info(dev,
493				 "can't get syscon-pllreset, sata dpll won't idle\n");
494			phy->dpll_reset_syscon = NULL;
495		} else {
496			if (of_property_read_u32_index(node,
497						       "syscon-pllreset", 1,
498						       &phy->dpll_reset_reg)) {
499				dev_err(dev,
500					"couldn't get pllreset reg. offset\n");
501				return -EINVAL;
502			}
503		}
504	}
505
506	return 0;
507}
508
509static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy)
510{
511	struct resource *res;
512	const struct of_device_id *match;
513	struct device *dev = phy->dev;
514	struct device_node *node = dev->of_node;
515	struct platform_device *pdev = to_platform_device(dev);
516
517	if (of_device_is_compatible(node, "ti,phy-pipe3-pcie"))
518		return 0;
519
520	match = of_match_device(ti_pipe3_id_table, dev);
521	if (!match)
522		return -EINVAL;
523
524	phy->dpll_map = (struct pipe3_dpll_map *)match->data;
525	if (!phy->dpll_map) {
526		dev_err(dev, "no DPLL data\n");
527		return -EINVAL;
528	}
529
530	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
531					   "pll_ctrl");
532	phy->pll_ctrl_base = devm_ioremap_resource(dev, res);
533	if (IS_ERR(phy->pll_ctrl_base))
534		return PTR_ERR(phy->pll_ctrl_base);
535
536	return 0;
537}
538
539static int ti_pipe3_probe(struct platform_device *pdev)
540{
541	struct ti_pipe3 *phy;
542	struct phy *generic_phy;
543	struct phy_provider *phy_provider;
544	struct device_node *node = pdev->dev.of_node;
545	struct device *dev = &pdev->dev;
546	int ret;
547
548	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
549	if (!phy)
550		return -ENOMEM;
551
552	phy->dev		= dev;
553
554	ret = ti_pipe3_get_pll_base(phy);
555	if (ret)
556		return ret;
557
558	ret = ti_pipe3_get_sysctrl(phy);
559	if (ret)
560		return ret;
561
562	ret = ti_pipe3_get_clk(phy);
563	if (ret)
564		return ret;
565
566	platform_set_drvdata(pdev, phy);
567	pm_runtime_enable(dev);
568
569	/*
570	 * Prevent auto-disable of refclk for SATA PHY due to Errata i783
571	 */
572	if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) {
573		if (!IS_ERR(phy->refclk)) {
574			clk_prepare_enable(phy->refclk);
575			phy->sata_refclk_enabled = true;
576		}
577	}
578
579	generic_phy = devm_phy_create(dev, NULL, &ops);
580	if (IS_ERR(generic_phy))
581		return PTR_ERR(generic_phy);
582
583	phy_set_drvdata(generic_phy, phy);
584
585	ti_pipe3_power_off(generic_phy);
586
587	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
588	if (IS_ERR(phy_provider))
589		return PTR_ERR(phy_provider);
590
591	return 0;
592}
593
594static int ti_pipe3_remove(struct platform_device *pdev)
595{
596	pm_runtime_disable(&pdev->dev);
597
598	return 0;
599}
600
601static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy)
602{
603	int ret = 0;
604
605	if (!IS_ERR(phy->refclk)) {
606		ret = clk_prepare_enable(phy->refclk);
607		if (ret) {
608			dev_err(phy->dev, "Failed to enable refclk %d\n", ret);
609			return ret;
610		}
611	}
612
613	if (!IS_ERR(phy->wkupclk)) {
614		ret = clk_prepare_enable(phy->wkupclk);
615		if (ret) {
616			dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
617			goto disable_refclk;
618		}
619	}
620
621	if (!IS_ERR(phy->div_clk)) {
622		ret = clk_prepare_enable(phy->div_clk);
623		if (ret) {
624			dev_err(phy->dev, "Failed to enable div_clk %d\n", ret);
625			goto disable_wkupclk;
626		}
627	}
628
629	return 0;
630
631disable_wkupclk:
632	if (!IS_ERR(phy->wkupclk))
633		clk_disable_unprepare(phy->wkupclk);
634
635disable_refclk:
636	if (!IS_ERR(phy->refclk))
637		clk_disable_unprepare(phy->refclk);
638
639	return ret;
640}
641
642static void ti_pipe3_disable_clocks(struct ti_pipe3 *phy)
643{
644	if (!IS_ERR(phy->wkupclk))
645		clk_disable_unprepare(phy->wkupclk);
646	if (!IS_ERR(phy->refclk)) {
647		clk_disable_unprepare(phy->refclk);
648		/*
649		 * SATA refclk needs an additional disable as we left it
650		 * on in probe to avoid Errata i783
651		 */
652		if (phy->sata_refclk_enabled) {
653			clk_disable_unprepare(phy->refclk);
654			phy->sata_refclk_enabled = false;
655		}
656	}
657
658	if (!IS_ERR(phy->div_clk))
659		clk_disable_unprepare(phy->div_clk);
660}
661
662static const struct of_device_id ti_pipe3_id_table[] = {
663	{
664		.compatible = "ti,phy-usb3",
665		.data = dpll_map_usb,
666	},
667	{
668		.compatible = "ti,omap-usb3",
669		.data = dpll_map_usb,
670	},
671	{
672		.compatible = "ti,phy-pipe3-sata",
673		.data = dpll_map_sata,
674	},
675	{
676		.compatible = "ti,phy-pipe3-pcie",
677	},
678	{}
679};
680MODULE_DEVICE_TABLE(of, ti_pipe3_id_table);
681
682static struct platform_driver ti_pipe3_driver = {
683	.probe		= ti_pipe3_probe,
684	.remove		= ti_pipe3_remove,
685	.driver		= {
686		.name	= "ti-pipe3",
687		.of_match_table = ti_pipe3_id_table,
688	},
689};
690
691module_platform_driver(ti_pipe3_driver);
692
693MODULE_ALIAS("platform:ti_pipe3");
694MODULE_AUTHOR("Texas Instruments Inc.");
695MODULE_DESCRIPTION("TI PIPE3 phy driver");
696MODULE_LICENSE("GPL v2");