Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
0004  */
0005 
0006 #include <linux/io.h>
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/of.h>
0010 #include <linux/of_address.h>
0011 #include <linux/time.h>
0012 #include <linux/delay.h>
0013 #include <linux/clk.h>
0014 #include <linux/slab.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/phy/phy.h>
0017 
0018 struct qcom_ipq806x_sata_phy {
0019     void __iomem *mmio;
0020     struct clk *cfg_clk;
0021     struct device *dev;
0022 };
0023 
0024 #define __set(v, a, b)  (((v) << (b)) & GENMASK(a, b))
0025 
0026 #define SATA_PHY_P0_PARAM0      0x200
0027 #define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(x)    __set(x, 17, 12)
0028 #define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK  GENMASK(17, 12)
0029 #define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2(x)    __set(x, 11, 6)
0030 #define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK  GENMASK(11, 6)
0031 #define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1(x)    __set(x, 5, 0)
0032 #define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK  GENMASK(5, 0)
0033 
0034 #define SATA_PHY_P0_PARAM1      0x204
0035 #define SATA_PHY_P0_PARAM1_RESERVED_BITS31_21(x)    __set(x, 31, 21)
0036 #define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(x)  __set(x, 20, 14)
0037 #define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK    GENMASK(20, 14)
0038 #define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(x)  __set(x, 13, 7)
0039 #define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK    GENMASK(13, 7)
0040 #define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(x)  __set(x, 6, 0)
0041 #define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK    GENMASK(6, 0)
0042 
0043 #define SATA_PHY_P0_PARAM2      0x208
0044 #define SATA_PHY_P0_PARAM2_RX_EQ(x) __set(x, 20, 18)
0045 #define SATA_PHY_P0_PARAM2_RX_EQ_MASK   GENMASK(20, 18)
0046 
0047 #define SATA_PHY_P0_PARAM3      0x20C
0048 #define SATA_PHY_SSC_EN         0x8
0049 #define SATA_PHY_P0_PARAM4      0x210
0050 #define SATA_PHY_REF_SSP_EN     0x2
0051 #define SATA_PHY_RESET          0x1
0052 
0053 static int qcom_ipq806x_sata_phy_init(struct phy *generic_phy)
0054 {
0055     struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
0056     u32 reg;
0057 
0058     /* Setting SSC_EN to 1 */
0059     reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM3);
0060     reg = reg | SATA_PHY_SSC_EN;
0061     writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM3);
0062 
0063     reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM0) &
0064             ~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK |
0065               SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK |
0066               SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK);
0067     reg |= SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(0xf);
0068     writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM0);
0069 
0070     reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM1) &
0071             ~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK |
0072               SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK |
0073               SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK);
0074     reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) |
0075         SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) |
0076         SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55);
0077     writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM1);
0078 
0079     reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM2) &
0080         ~SATA_PHY_P0_PARAM2_RX_EQ_MASK;
0081     reg |= SATA_PHY_P0_PARAM2_RX_EQ(0x3);
0082     writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM2);
0083 
0084     /* Setting PHY_RESET to 1 */
0085     reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
0086     reg = reg | SATA_PHY_RESET;
0087     writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
0088 
0089     /* Setting REF_SSP_EN to 1 */
0090     reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
0091     reg = reg | SATA_PHY_REF_SSP_EN | SATA_PHY_RESET;
0092     writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
0093 
0094     /* make sure all changes complete before we let the PHY out of reset */
0095     mb();
0096 
0097     /* sleep for max. 50us more to combine processor wakeups */
0098     usleep_range(20, 20 + 50);
0099 
0100     /* Clearing PHY_RESET to 0 */
0101     reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
0102     reg = reg & ~SATA_PHY_RESET;
0103     writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
0104 
0105     return 0;
0106 }
0107 
0108 static int qcom_ipq806x_sata_phy_exit(struct phy *generic_phy)
0109 {
0110     struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
0111     u32 reg;
0112 
0113     /* Setting PHY_RESET to 1 */
0114     reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
0115     reg = reg | SATA_PHY_RESET;
0116     writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
0117 
0118     return 0;
0119 }
0120 
0121 static const struct phy_ops qcom_ipq806x_sata_phy_ops = {
0122     .init       = qcom_ipq806x_sata_phy_init,
0123     .exit       = qcom_ipq806x_sata_phy_exit,
0124     .owner      = THIS_MODULE,
0125 };
0126 
0127 static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
0128 {
0129     struct qcom_ipq806x_sata_phy *phy;
0130     struct device *dev = &pdev->dev;
0131     struct phy_provider *phy_provider;
0132     struct phy *generic_phy;
0133     int ret;
0134 
0135     phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
0136     if (!phy)
0137         return -ENOMEM;
0138 
0139     phy->mmio = devm_platform_ioremap_resource(pdev, 0);
0140     if (IS_ERR(phy->mmio))
0141         return PTR_ERR(phy->mmio);
0142 
0143     generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops);
0144     if (IS_ERR(generic_phy)) {
0145         dev_err(dev, "%s: failed to create phy\n", __func__);
0146         return PTR_ERR(generic_phy);
0147     }
0148 
0149     phy->dev = dev;
0150     phy_set_drvdata(generic_phy, phy);
0151     platform_set_drvdata(pdev, phy);
0152 
0153     phy->cfg_clk = devm_clk_get(dev, "cfg");
0154     if (IS_ERR(phy->cfg_clk)) {
0155         dev_err(dev, "Failed to get sata cfg clock\n");
0156         return PTR_ERR(phy->cfg_clk);
0157     }
0158 
0159     ret = clk_prepare_enable(phy->cfg_clk);
0160     if (ret)
0161         return ret;
0162 
0163     phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0164     if (IS_ERR(phy_provider)) {
0165         clk_disable_unprepare(phy->cfg_clk);
0166         dev_err(dev, "%s: failed to register phy\n", __func__);
0167         return PTR_ERR(phy_provider);
0168     }
0169 
0170     return 0;
0171 }
0172 
0173 static int qcom_ipq806x_sata_phy_remove(struct platform_device *pdev)
0174 {
0175     struct qcom_ipq806x_sata_phy *phy = platform_get_drvdata(pdev);
0176 
0177     clk_disable_unprepare(phy->cfg_clk);
0178 
0179     return 0;
0180 }
0181 
0182 static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = {
0183     { .compatible = "qcom,ipq806x-sata-phy" },
0184     { },
0185 };
0186 MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match);
0187 
0188 static struct platform_driver qcom_ipq806x_sata_phy_driver = {
0189     .probe  = qcom_ipq806x_sata_phy_probe,
0190     .remove = qcom_ipq806x_sata_phy_remove,
0191     .driver = {
0192         .name   = "qcom-ipq806x-sata-phy",
0193         .of_match_table = qcom_ipq806x_sata_phy_of_match,
0194     }
0195 };
0196 module_platform_driver(qcom_ipq806x_sata_phy_driver);
0197 
0198 MODULE_DESCRIPTION("QCOM IPQ806x SATA PHY driver");
0199 MODULE_LICENSE("GPL v2");