phy-ti-pipe3.c 10.7 KB
Newer Older
1
/*
2
 * phy-ti-pipe3 - PIPE3 PHY driver.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Author: Kishon Vijay Abraham I <kishon@ti.com>
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
22
#include <linux/phy/phy.h>
23 24 25
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/err.h>
26
#include <linux/io.h>
27 28
#include <linux/pm_runtime.h>
#include <linux/delay.h>
29
#include <linux/phy/omap_control_phy.h>
30
#include <linux/of_platform.h>
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

#define	PLL_STATUS		0x00000004
#define	PLL_GO			0x00000008
#define	PLL_CONFIGURATION1	0x0000000C
#define	PLL_CONFIGURATION2	0x00000010
#define	PLL_CONFIGURATION3	0x00000014
#define	PLL_CONFIGURATION4	0x00000020

#define	PLL_REGM_MASK		0x001FFE00
#define	PLL_REGM_SHIFT		0x9
#define	PLL_REGM_F_MASK		0x0003FFFF
#define	PLL_REGM_F_SHIFT	0x0
#define	PLL_REGN_MASK		0x000001FE
#define	PLL_REGN_SHIFT		0x1
#define	PLL_SELFREQDCO_MASK	0x0000000E
#define	PLL_SELFREQDCO_SHIFT	0x1
#define	PLL_SD_MASK		0x0003FC00
48
#define	PLL_SD_SHIFT		10
49 50 51 52 53 54 55
#define	SET_PLL_GO		0x1
#define	PLL_TICOPWDN		0x10000
#define	PLL_LOCK		0x2
#define	PLL_IDLE		0x1

/*
 * This is an Empirical value that works, need to confirm the actual
56 57
 * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
 * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
58 59 60
 */
# define PLL_IDLE_TIME  100;

61 62 63 64 65 66 67 68
struct pipe3_dpll_params {
	u16	m;
	u8	n;
	u8	freq:3;
	u8	sd;
	u32	mf;
};

69 70 71 72 73
struct pipe3_dpll_map {
	unsigned long rate;
	struct pipe3_dpll_params params;
};

74 75 76 77 78 79
struct ti_pipe3 {
	void __iomem		*pll_ctrl_base;
	struct device		*dev;
	struct device		*control_dev;
	struct clk		*wkupclk;
	struct clk		*sys_clk;
80
	struct clk		*refclk;
81
	struct pipe3_dpll_map	*dpll_map;
82 83
};

84
static struct pipe3_dpll_map dpll_map_usb[] = {
85 86 87 88 89 90
	{12000000, {1250, 5, 4, 20, 0} },	/* 12 MHz */
	{16800000, {3125, 20, 4, 20, 0} },	/* 16.8 MHz */
	{19200000, {1172, 8, 4, 20, 65537} },	/* 19.2 MHz */
	{20000000, {1000, 7, 4, 10, 0} },	/* 20 MHz */
	{26000000, {1250, 12, 4, 20, 0} },	/* 26 MHz */
	{38400000, {3125, 47, 4, 20, 92843} },	/* 38.4 MHz */
91 92 93 94 95 96 97 98 99 100 101
	{ },					/* Terminator */
};

static struct pipe3_dpll_map dpll_map_sata[] = {
	{12000000, {1000, 7, 4, 6, 0} },	/* 12 MHz */
	{16800000, {714, 7, 4, 6, 0} },		/* 16.8 MHz */
	{19200000, {625, 7, 4, 6, 0} },		/* 19.2 MHz */
	{20000000, {600, 7, 4, 6, 0} },		/* 20 MHz */
	{26000000, {461, 7, 4, 6, 0} },		/* 26 MHz */
	{38400000, {312, 7, 4, 6, 0} },		/* 38.4 MHz */
	{ },					/* Terminator */
102 103
};

104 105 106 107 108 109 110 111 112 113 114
static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset)
{
	return __raw_readl(addr + offset);
}

static inline void ti_pipe3_writel(void __iomem *addr, unsigned offset,
	u32 data)
{
	__raw_writel(data, addr + offset);
}

115
static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(struct ti_pipe3 *phy)
116
{
117 118
	unsigned long rate;
	struct pipe3_dpll_map *dpll_map = phy->dpll_map;
119

120 121 122 123 124
	rate = clk_get_rate(phy->sys_clk);

	for (; dpll_map->rate; dpll_map++) {
		if (rate == dpll_map->rate)
			return &dpll_map->params;
125 126
	}

127 128
	dev_err(phy->dev, "No DPLL configuration for %lu Hz SYS CLK\n", rate);

129
	return NULL;
130 131
}

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
static int ti_pipe3_power_off(struct phy *x)
{
	struct ti_pipe3 *phy = phy_get_drvdata(x);
	int val;
	int timeout = PLL_IDLE_TIME;

	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
	val |= PLL_IDLE;
	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);

	do {
		val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
		if (val & PLL_TICOPWDN)
			break;
		udelay(5);
	} while (--timeout);

	if (!timeout) {
		dev_err(phy->dev, "power off failed\n");
		return -EBUSY;
	}

154
	omap_control_phy_power(phy->control_dev, 0);
155 156 157 158 159

	return 0;
}

static int ti_pipe3_power_on(struct phy *x)
160
{
161 162
	struct ti_pipe3 *phy = phy_get_drvdata(x);
	int val;
163 164
	int timeout = PLL_IDLE_TIME;

165 166 167 168 169 170 171 172 173 174 175 176 177 178
	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
	val &= ~PLL_IDLE;
	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);

	do {
		val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
		if (!(val & PLL_TICOPWDN))
			break;
		udelay(5);
	} while (--timeout);

	if (!timeout) {
		dev_err(phy->dev, "power on failed\n");
		return -EBUSY;
179 180 181 182 183
	}

	return 0;
}

184
static void ti_pipe3_dpll_relock(struct ti_pipe3 *phy)
185 186 187 188
{
	u32		val;
	unsigned long	timeout;

189
	ti_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
190 191 192

	timeout = jiffies + msecs_to_jiffies(20);
	do {
193
		val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
194 195 196 197 198
		if (val & PLL_LOCK)
			break;
	} while (!WARN_ON(time_after(jiffies, timeout)));
}

199
static int ti_pipe3_dpll_lock(struct ti_pipe3 *phy)
200 201
{
	u32			val;
202
	struct pipe3_dpll_params *dpll_params;
203

204 205
	dpll_params = ti_pipe3_get_dpll_params(phy);
	if (!dpll_params)
206 207
		return -EINVAL;

208
	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
209
	val &= ~PLL_REGN_MASK;
210
	val |= dpll_params->n << PLL_REGN_SHIFT;
211
	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
212

213
	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
214
	val &= ~PLL_SELFREQDCO_MASK;
215
	val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
216
	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
217

218
	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
219
	val &= ~PLL_REGM_MASK;
220
	val |= dpll_params->m << PLL_REGM_SHIFT;
221
	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
222

223
	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
224
	val &= ~PLL_REGM_F_MASK;
225
	val |= dpll_params->mf << PLL_REGM_F_SHIFT;
226
	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
227

228
	val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
229
	val &= ~PLL_SD_MASK;
230
	val |= dpll_params->sd << PLL_SD_SHIFT;
231
	ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
232

233
	ti_pipe3_dpll_relock(phy);
234 235 236 237

	return 0;
}

238
static int ti_pipe3_init(struct phy *x)
239
{
240
	struct ti_pipe3 *phy = phy_get_drvdata(x);
241 242
	int ret;

243
	ret = ti_pipe3_dpll_lock(phy);
244 245
	if (ret)
		return ret;
246

247
	omap_control_phy_power(phy->control_dev, 1);
248 249 250 251

	return 0;
}

252 253 254 255 256 257 258
static struct phy_ops ops = {
	.init		= ti_pipe3_init,
	.power_on	= ti_pipe3_power_on,
	.power_off	= ti_pipe3_power_off,
	.owner		= THIS_MODULE,
};

259 260 261 262
#ifdef CONFIG_OF
static const struct of_device_id ti_pipe3_id_table[];
#endif

263
static int ti_pipe3_probe(struct platform_device *pdev)
264
{
265 266 267
	struct ti_pipe3 *phy;
	struct phy *generic_phy;
	struct phy_provider *phy_provider;
268 269 270 271
	struct resource *res;
	struct device_node *node = pdev->dev.of_node;
	struct device_node *control_node;
	struct platform_device *control_pdev;
272
	const struct of_device_id *match;
273

274 275
	match = of_match_device(of_match_ptr(ti_pipe3_id_table), &pdev->dev);
	if (!match)
276
		return -EINVAL;
277 278 279

	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
	if (!phy) {
280
		dev_err(&pdev->dev, "unable to alloc mem for TI PIPE3 PHY\n");
281 282 283
		return -ENOMEM;
	}

284 285 286 287 288 289
	phy->dpll_map = (struct pipe3_dpll_map *)match->data;
	if (!phy->dpll_map) {
		dev_err(&pdev->dev, "no DPLL data\n");
		return -EINVAL;
	}

290
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
291 292 293
	phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(phy->pll_ctrl_base))
		return PTR_ERR(phy->pll_ctrl_base);
294 295 296

	phy->dev		= &pdev->dev;

297
	phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
298
	if (IS_ERR(phy->wkupclk)) {
299
		dev_err(&pdev->dev, "unable to get wkupclk\n");
300 301 302
		return PTR_ERR(phy->wkupclk);
	}

303 304 305 306
	phy->refclk = devm_clk_get(phy->dev, "refclk");
	if (IS_ERR(phy->refclk)) {
		dev_err(&pdev->dev, "unable to get refclk\n");
		return PTR_ERR(phy->refclk);
307 308
	}

309
	phy->sys_clk = devm_clk_get(phy->dev, "sysclk");
310
	if (IS_ERR(phy->sys_clk)) {
311
		dev_err(&pdev->dev, "unable to get sysclk\n");
312 313 314
		return -EINVAL;
	}

315 316 317 318
	control_node = of_parse_phandle(node, "ctrl-module", 0);
	if (!control_node) {
		dev_err(&pdev->dev, "Failed to get control device phandle\n");
		return -EINVAL;
319
	}
320

321 322 323 324 325 326 327
	control_pdev = of_find_device_by_node(control_node);
	if (!control_pdev) {
		dev_err(&pdev->dev, "Failed to get control device\n");
		return -EINVAL;
	}

	phy->control_dev = &control_pdev->dev;
328

329
	omap_control_phy_power(phy->control_dev, 0);
330 331 332

	platform_set_drvdata(pdev, phy);
	pm_runtime_enable(phy->dev);
333 334 335 336 337 338 339 340 341 342 343

	generic_phy = devm_phy_create(phy->dev, &ops, NULL);
	if (IS_ERR(generic_phy))
		return PTR_ERR(generic_phy);

	phy_set_drvdata(generic_phy, phy);
	phy_provider = devm_of_phy_provider_register(phy->dev,
			of_phy_simple_xlate);
	if (IS_ERR(phy_provider))
		return PTR_ERR(phy_provider);

344 345 346 347 348
	pm_runtime_get(&pdev->dev);

	return 0;
}

349
static int ti_pipe3_remove(struct platform_device *pdev)
350 351 352 353 354 355 356 357 358 359
{
	if (!pm_runtime_suspended(&pdev->dev))
		pm_runtime_put(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	return 0;
}

#ifdef CONFIG_PM_RUNTIME

360
static int ti_pipe3_runtime_suspend(struct device *dev)
361
{
362
	struct ti_pipe3	*phy = dev_get_drvdata(dev);
363

364 365 366 367
	if (!IS_ERR(phy->wkupclk))
		clk_disable_unprepare(phy->wkupclk);
	if (!IS_ERR(phy->refclk))
		clk_disable_unprepare(phy->refclk);
368 369 370 371

	return 0;
}

372
static int ti_pipe3_runtime_resume(struct device *dev)
373 374
{
	u32 ret = 0;
375
	struct ti_pipe3	*phy = dev_get_drvdata(dev);
376

377 378 379 380 381 382
	if (!IS_ERR(phy->refclk)) {
		ret = clk_prepare_enable(phy->refclk);
		if (ret) {
			dev_err(phy->dev, "Failed to enable refclk %d\n", ret);
			goto err1;
		}
383 384
	}

385 386 387 388 389 390
	if (!IS_ERR(phy->wkupclk)) {
		ret = clk_prepare_enable(phy->wkupclk);
		if (ret) {
			dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
			goto err2;
		}
391 392 393 394 395
	}

	return 0;

err2:
396 397
	if (!IS_ERR(phy->refclk))
		clk_disable_unprepare(phy->refclk);
398 399 400 401 402

err1:
	return ret;
}

403 404 405
static const struct dev_pm_ops ti_pipe3_pm_ops = {
	SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend,
			   ti_pipe3_runtime_resume, NULL)
406 407
};

408
#define DEV_PM_OPS     (&ti_pipe3_pm_ops)
409 410 411 412 413
#else
#define DEV_PM_OPS     NULL
#endif

#ifdef CONFIG_OF
414
static const struct of_device_id ti_pipe3_id_table[] = {
415 416 417 418 419 420 421 422 423 424 425 426
	{
		.compatible = "ti,phy-usb3",
		.data = dpll_map_usb,
	},
	{
		.compatible = "ti,omap-usb3",
		.data = dpll_map_usb,
	},
	{
		.compatible = "ti,phy-pipe3-sata",
		.data = dpll_map_sata,
	},
427 428
	{}
};
429
MODULE_DEVICE_TABLE(of, ti_pipe3_id_table);
430 431
#endif

432 433 434
static struct platform_driver ti_pipe3_driver = {
	.probe		= ti_pipe3_probe,
	.remove		= ti_pipe3_remove,
435
	.driver		= {
436
		.name	= "ti-pipe3",
437 438
		.owner	= THIS_MODULE,
		.pm	= DEV_PM_OPS,
439
		.of_match_table = of_match_ptr(ti_pipe3_id_table),
440 441 442
	},
};

443
module_platform_driver(ti_pipe3_driver);
444

445
MODULE_ALIAS("platform: ti_pipe3");
446
MODULE_AUTHOR("Texas Instruments Inc.");
447
MODULE_DESCRIPTION("TI PIPE3 phy driver");
448
MODULE_LICENSE("GPL v2");