phy-tegra194-p2u.c (3026B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * P2U (PIPE to UPHY) driver for Tegra T194 SoC 4 * 5 * Copyright (C) 2019 NVIDIA Corporation. 6 * 7 * Author: Vidya Sagar <vidyas@nvidia.com> 8 */ 9 10#include <linux/err.h> 11#include <linux/io.h> 12#include <linux/module.h> 13#include <linux/of.h> 14#include <linux/of_platform.h> 15#include <linux/phy/phy.h> 16 17#define P2U_PERIODIC_EQ_CTRL_GEN3 0xc0 18#define P2U_PERIODIC_EQ_CTRL_GEN3_PERIODIC_EQ_EN BIT(0) 19#define P2U_PERIODIC_EQ_CTRL_GEN3_INIT_PRESET_EQ_TRAIN_EN BIT(1) 20#define P2U_PERIODIC_EQ_CTRL_GEN4 0xc4 21#define P2U_PERIODIC_EQ_CTRL_GEN4_INIT_PRESET_EQ_TRAIN_EN BIT(1) 22 23#define P2U_RX_DEBOUNCE_TIME 0xa4 24#define P2U_RX_DEBOUNCE_TIME_DEBOUNCE_TIMER_MASK 0xffff 25#define P2U_RX_DEBOUNCE_TIME_DEBOUNCE_TIMER_VAL 160 26 27struct tegra_p2u { 28 void __iomem *base; 29}; 30 31static inline void p2u_writel(struct tegra_p2u *phy, const u32 value, 32 const u32 reg) 33{ 34 writel_relaxed(value, phy->base + reg); 35} 36 37static inline u32 p2u_readl(struct tegra_p2u *phy, const u32 reg) 38{ 39 return readl_relaxed(phy->base + reg); 40} 41 42static int tegra_p2u_power_on(struct phy *x) 43{ 44 struct tegra_p2u *phy = phy_get_drvdata(x); 45 u32 val; 46 47 val = p2u_readl(phy, P2U_PERIODIC_EQ_CTRL_GEN3); 48 val &= ~P2U_PERIODIC_EQ_CTRL_GEN3_PERIODIC_EQ_EN; 49 val |= P2U_PERIODIC_EQ_CTRL_GEN3_INIT_PRESET_EQ_TRAIN_EN; 50 p2u_writel(phy, val, P2U_PERIODIC_EQ_CTRL_GEN3); 51 52 val = p2u_readl(phy, P2U_PERIODIC_EQ_CTRL_GEN4); 53 val |= P2U_PERIODIC_EQ_CTRL_GEN4_INIT_PRESET_EQ_TRAIN_EN; 54 p2u_writel(phy, val, P2U_PERIODIC_EQ_CTRL_GEN4); 55 56 val = p2u_readl(phy, P2U_RX_DEBOUNCE_TIME); 57 val &= ~P2U_RX_DEBOUNCE_TIME_DEBOUNCE_TIMER_MASK; 58 val |= P2U_RX_DEBOUNCE_TIME_DEBOUNCE_TIMER_VAL; 59 p2u_writel(phy, val, P2U_RX_DEBOUNCE_TIME); 60 61 return 0; 62} 63 64static const struct phy_ops ops = { 65 .power_on = tegra_p2u_power_on, 66 .owner = THIS_MODULE, 67}; 68 69static int tegra_p2u_probe(struct platform_device *pdev) 70{ 71 struct phy_provider *phy_provider; 72 struct device *dev = &pdev->dev; 73 struct phy *generic_phy; 74 struct tegra_p2u *phy; 75 76 phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); 77 if (!phy) 78 return -ENOMEM; 79 80 phy->base = devm_platform_ioremap_resource_byname(pdev, "ctl"); 81 if (IS_ERR(phy->base)) 82 return PTR_ERR(phy->base); 83 84 platform_set_drvdata(pdev, phy); 85 86 generic_phy = devm_phy_create(dev, NULL, &ops); 87 if (IS_ERR(generic_phy)) 88 return PTR_ERR(generic_phy); 89 90 phy_set_drvdata(generic_phy, phy); 91 92 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 93 if (IS_ERR(phy_provider)) 94 return PTR_ERR(phy_provider); 95 96 return 0; 97} 98 99static const struct of_device_id tegra_p2u_id_table[] = { 100 { 101 .compatible = "nvidia,tegra194-p2u", 102 }, 103 {} 104}; 105MODULE_DEVICE_TABLE(of, tegra_p2u_id_table); 106 107static struct platform_driver tegra_p2u_driver = { 108 .probe = tegra_p2u_probe, 109 .driver = { 110 .name = "tegra194-p2u", 111 .of_match_table = tegra_p2u_id_table, 112 }, 113}; 114module_platform_driver(tegra_p2u_driver); 115 116MODULE_AUTHOR("Vidya Sagar <vidyas@nvidia.com>"); 117MODULE_DESCRIPTION("NVIDIA Tegra194 PIPE2UPHY PHY driver"); 118MODULE_LICENSE("GPL v2");