Skip to content

Commit 7021dea

Browse files
committed
Merge tag 'phy-for-4.2-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-linus
Kishon writes: phy: for 4.2-rc *) Fix PIPE3 PM so that all its users (PCIe, SATA, USB) can idle and resume *) Fix a compiler error in pxa *) Fix pll divider values in berlin-usb phy driver Signed-off-by: Kishon Vijay Abraham I <[email protected]>
2 parents aca3a04 + dcb54fc commit 7021dea

File tree

3 files changed

+45
-133
lines changed

3 files changed

+45
-133
lines changed

drivers/phy/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ config PHY_EXYNOS_MIPI_VIDEO
5656

5757
config PHY_PXA_28NM_HSIC
5858
tristate "Marvell USB HSIC 28nm PHY Driver"
59+
depends on HAS_IOMEM
5960
select GENERIC_PHY
6061
help
6162
Enable this to support Marvell USB HSIC PHY driver for Marvell
@@ -66,6 +67,7 @@ config PHY_PXA_28NM_HSIC
6667

6768
config PHY_PXA_28NM_USB2
6869
tristate "Marvell USB 2.0 28nm PHY Driver"
70+
depends on HAS_IOMEM
6971
select GENERIC_PHY
7072
help
7173
Enable this to support Marvell USB 2.0 PHY driver for Marvell

drivers/phy/phy-berlin-usb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@
105105

106106
static const u32 phy_berlin_pll_dividers[] = {
107107
/* Berlin 2 */
108-
CLK_REF_DIV(0xc) | FEEDBACK_CLK_DIV(0x54),
109-
/* Berlin 2CD */
110108
CLK_REF_DIV(0x6) | FEEDBACK_CLK_DIV(0x55),
109+
/* Berlin 2CD/Q */
110+
CLK_REF_DIV(0xc) | FEEDBACK_CLK_DIV(0x54),
111111
};
112112

113113
struct phy_berlin_usb_priv {

drivers/phy/phy-ti-pipe3.c

Lines changed: 41 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include <linux/delay.h>
2929
#include <linux/phy/omap_control_phy.h>
3030
#include <linux/of_platform.h>
31-
#include <linux/spinlock.h>
3231

3332
#define PLL_STATUS 0x00000004
3433
#define PLL_GO 0x00000008
@@ -83,10 +82,6 @@ struct ti_pipe3 {
8382
struct clk *refclk;
8483
struct clk *div_clk;
8584
struct pipe3_dpll_map *dpll_map;
86-
bool enabled;
87-
spinlock_t lock; /* serialize clock enable/disable */
88-
/* the below flag is needed specifically for SATA */
89-
bool refclk_enabled;
9085
};
9186

9287
static struct pipe3_dpll_map dpll_map_usb[] = {
@@ -137,6 +132,9 @@ static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(struct ti_pipe3 *phy)
137132
return NULL;
138133
}
139134

135+
static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy);
136+
static void ti_pipe3_disable_clocks(struct ti_pipe3 *phy);
137+
140138
static int ti_pipe3_power_off(struct phy *x)
141139
{
142140
struct ti_pipe3 *phy = phy_get_drvdata(x);
@@ -217,6 +215,7 @@ static int ti_pipe3_init(struct phy *x)
217215
u32 val;
218216
int ret = 0;
219217

218+
ti_pipe3_enable_clocks(phy);
220219
/*
221220
* Set pcie_pcs register to 0x96 for proper functioning of phy
222221
* as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table
@@ -250,33 +249,35 @@ static int ti_pipe3_exit(struct phy *x)
250249
u32 val;
251250
unsigned long timeout;
252251

253-
/* SATA DPLL can't be powered down due to Errata i783 and PCIe
254-
* does not have internal DPLL
255-
*/
256-
if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") ||
257-
of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie"))
252+
/* SATA DPLL can't be powered down due to Errata i783 */
253+
if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata"))
258254
return 0;
259255

260-
/* Put DPLL in IDLE mode */
261-
val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
262-
val |= PLL_IDLE;
263-
ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
264-
265-
/* wait for LDO and Oscillator to power down */
266-
timeout = jiffies + msecs_to_jiffies(PLL_IDLE_TIME);
267-
do {
268-
cpu_relax();
269-
val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
270-
if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN))
271-
break;
272-
} while (!time_after(jiffies, timeout));
256+
/* PCIe doesn't have internal DPLL */
257+
if (!of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) {
258+
/* Put DPLL in IDLE mode */
259+
val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
260+
val |= PLL_IDLE;
261+
ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
273262

274-
if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) {
275-
dev_err(phy->dev, "Failed to power down: PLL_STATUS 0x%x\n",
276-
val);
277-
return -EBUSY;
263+
/* wait for LDO and Oscillator to power down */
264+
timeout = jiffies + msecs_to_jiffies(PLL_IDLE_TIME);
265+
do {
266+
cpu_relax();
267+
val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
268+
if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN))
269+
break;
270+
} while (!time_after(jiffies, timeout));
271+
272+
if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) {
273+
dev_err(phy->dev, "Failed to power down: PLL_STATUS 0x%x\n",
274+
val);
275+
return -EBUSY;
276+
}
278277
}
279278

279+
ti_pipe3_disable_clocks(phy);
280+
280281
return 0;
281282
}
282283
static struct phy_ops ops = {
@@ -306,7 +307,6 @@ static int ti_pipe3_probe(struct platform_device *pdev)
306307
return -ENOMEM;
307308

308309
phy->dev = &pdev->dev;
309-
spin_lock_init(&phy->lock);
310310

311311
if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
312312
match = of_match_device(ti_pipe3_id_table, &pdev->dev);
@@ -402,6 +402,10 @@ static int ti_pipe3_probe(struct platform_device *pdev)
402402

403403
platform_set_drvdata(pdev, phy);
404404
pm_runtime_enable(phy->dev);
405+
/* Prevent auto-disable of refclk for SATA PHY due to Errata i783 */
406+
if (of_device_is_compatible(node, "ti,phy-pipe3-sata"))
407+
if (!IS_ERR(phy->refclk))
408+
clk_prepare_enable(phy->refclk);
405409

406410
generic_phy = devm_phy_create(phy->dev, NULL, &ops);
407411
if (IS_ERR(generic_phy))
@@ -413,160 +417,67 @@ static int ti_pipe3_probe(struct platform_device *pdev)
413417
if (IS_ERR(phy_provider))
414418
return PTR_ERR(phy_provider);
415419

416-
pm_runtime_get(&pdev->dev);
417-
418420
return 0;
419421
}
420422

421423
static int ti_pipe3_remove(struct platform_device *pdev)
422424
{
423-
if (!pm_runtime_suspended(&pdev->dev))
424-
pm_runtime_put(&pdev->dev);
425425
pm_runtime_disable(&pdev->dev);
426426

427427
return 0;
428428
}
429429

430-
#ifdef CONFIG_PM
431-
static int ti_pipe3_enable_refclk(struct ti_pipe3 *phy)
430+
static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy)
432431
{
433-
if (!IS_ERR(phy->refclk) && !phy->refclk_enabled) {
434-
int ret;
432+
int ret = 0;
435433

434+
if (!IS_ERR(phy->refclk)) {
436435
ret = clk_prepare_enable(phy->refclk);
437436
if (ret) {
438437
dev_err(phy->dev, "Failed to enable refclk %d\n", ret);
439438
return ret;
440439
}
441-
phy->refclk_enabled = true;
442440
}
443441

444-
return 0;
445-
}
446-
447-
static void ti_pipe3_disable_refclk(struct ti_pipe3 *phy)
448-
{
449-
if (!IS_ERR(phy->refclk))
450-
clk_disable_unprepare(phy->refclk);
451-
452-
phy->refclk_enabled = false;
453-
}
454-
455-
static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy)
456-
{
457-
int ret = 0;
458-
unsigned long flags;
459-
460-
spin_lock_irqsave(&phy->lock, flags);
461-
if (phy->enabled)
462-
goto err1;
463-
464-
ret = ti_pipe3_enable_refclk(phy);
465-
if (ret)
466-
goto err1;
467-
468442
if (!IS_ERR(phy->wkupclk)) {
469443
ret = clk_prepare_enable(phy->wkupclk);
470444
if (ret) {
471445
dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
472-
goto err2;
446+
goto disable_refclk;
473447
}
474448
}
475449

476450
if (!IS_ERR(phy->div_clk)) {
477451
ret = clk_prepare_enable(phy->div_clk);
478452
if (ret) {
479453
dev_err(phy->dev, "Failed to enable div_clk %d\n", ret);
480-
goto err3;
454+
goto disable_wkupclk;
481455
}
482456
}
483457

484-
phy->enabled = true;
485-
spin_unlock_irqrestore(&phy->lock, flags);
486458
return 0;
487459

488-
err3:
460+
disable_wkupclk:
489461
if (!IS_ERR(phy->wkupclk))
490462
clk_disable_unprepare(phy->wkupclk);
491463

492-
err2:
464+
disable_refclk:
493465
if (!IS_ERR(phy->refclk))
494466
clk_disable_unprepare(phy->refclk);
495467

496-
ti_pipe3_disable_refclk(phy);
497-
err1:
498-
spin_unlock_irqrestore(&phy->lock, flags);
499468
return ret;
500469
}
501470

502471
static void ti_pipe3_disable_clocks(struct ti_pipe3 *phy)
503472
{
504-
unsigned long flags;
505-
506-
spin_lock_irqsave(&phy->lock, flags);
507-
if (!phy->enabled) {
508-
spin_unlock_irqrestore(&phy->lock, flags);
509-
return;
510-
}
511-
512473
if (!IS_ERR(phy->wkupclk))
513474
clk_disable_unprepare(phy->wkupclk);
514-
/* Don't disable refclk for SATA PHY due to Errata i783 */
515-
if (!of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata"))
516-
ti_pipe3_disable_refclk(phy);
475+
if (!IS_ERR(phy->refclk))
476+
clk_disable_unprepare(phy->refclk);
517477
if (!IS_ERR(phy->div_clk))
518478
clk_disable_unprepare(phy->div_clk);
519-
phy->enabled = false;
520-
spin_unlock_irqrestore(&phy->lock, flags);
521-
}
522-
523-
static int ti_pipe3_runtime_suspend(struct device *dev)
524-
{
525-
struct ti_pipe3 *phy = dev_get_drvdata(dev);
526-
527-
ti_pipe3_disable_clocks(phy);
528-
return 0;
529479
}
530480

531-
static int ti_pipe3_runtime_resume(struct device *dev)
532-
{
533-
struct ti_pipe3 *phy = dev_get_drvdata(dev);
534-
int ret = 0;
535-
536-
ret = ti_pipe3_enable_clocks(phy);
537-
return ret;
538-
}
539-
540-
static int ti_pipe3_suspend(struct device *dev)
541-
{
542-
struct ti_pipe3 *phy = dev_get_drvdata(dev);
543-
544-
ti_pipe3_disable_clocks(phy);
545-
return 0;
546-
}
547-
548-
static int ti_pipe3_resume(struct device *dev)
549-
{
550-
struct ti_pipe3 *phy = dev_get_drvdata(dev);
551-
int ret;
552-
553-
ret = ti_pipe3_enable_clocks(phy);
554-
if (ret)
555-
return ret;
556-
557-
pm_runtime_disable(dev);
558-
pm_runtime_set_active(dev);
559-
pm_runtime_enable(dev);
560-
return 0;
561-
}
562-
#endif
563-
564-
static const struct dev_pm_ops ti_pipe3_pm_ops = {
565-
SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend,
566-
ti_pipe3_runtime_resume, NULL)
567-
SET_SYSTEM_SLEEP_PM_OPS(ti_pipe3_suspend, ti_pipe3_resume)
568-
};
569-
570481
static const struct of_device_id ti_pipe3_id_table[] = {
571482
{
572483
.compatible = "ti,phy-usb3",
@@ -592,7 +503,6 @@ static struct platform_driver ti_pipe3_driver = {
592503
.remove = ti_pipe3_remove,
593504
.driver = {
594505
.name = "ti-pipe3",
595-
.pm = &ti_pipe3_pm_ops,
596506
.of_match_table = ti_pipe3_id_table,
597507
},
598508
};

0 commit comments

Comments
 (0)