0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk.h>
0011 #include <linux/delay.h>
0012 #include <linux/io.h>
0013 #include <linux/i2c.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/of.h>
0017 #include <linux/of_address.h>
0018 #include <linux/phy/phy.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/regmap.h>
0021 #include <linux/spinlock.h>
0022 #include <linux/mfd/syscon.h>
0023
0024 #define SATAPHY_CONTROL_OFFSET 0x0724
0025 #define EXYNOS5_SATAPHY_PMU_ENABLE BIT(0)
0026 #define EXYNOS5_SATA_RESET 0x4
0027 #define RESET_GLOBAL_RST_N BIT(0)
0028 #define RESET_CMN_RST_N BIT(1)
0029 #define RESET_CMN_BLOCK_RST_N BIT(2)
0030 #define RESET_CMN_I2C_RST_N BIT(3)
0031 #define RESET_TX_RX_PIPE_RST_N BIT(4)
0032 #define RESET_TX_RX_BLOCK_RST_N BIT(5)
0033 #define RESET_TX_RX_I2C_RST_N (BIT(6) | BIT(7))
0034 #define LINK_RESET 0xf0000
0035 #define EXYNOS5_SATA_MODE0 0x10
0036 #define SATA_SPD_GEN3 BIT(1)
0037 #define EXYNOS5_SATA_CTRL0 0x14
0038 #define CTRL0_P0_PHY_CALIBRATED_SEL BIT(9)
0039 #define CTRL0_P0_PHY_CALIBRATED BIT(8)
0040 #define EXYNOS5_SATA_PHSATA_CTRLM 0xe0
0041 #define PHCTRLM_REF_RATE BIT(1)
0042 #define PHCTRLM_HIGH_SPEED BIT(0)
0043 #define EXYNOS5_SATA_PHSATA_STATM 0xf0
0044 #define PHSTATM_PLL_LOCKED BIT(0)
0045
0046 #define PHY_PLL_TIMEOUT (usecs_to_jiffies(1000))
0047
0048 struct exynos_sata_phy {
0049 struct phy *phy;
0050 struct clk *phyclk;
0051 void __iomem *regs;
0052 struct regmap *pmureg;
0053 struct i2c_client *client;
0054 };
0055
0056 static int wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit,
0057 u32 status)
0058 {
0059 unsigned long timeout = jiffies + PHY_PLL_TIMEOUT;
0060
0061 while (time_before(jiffies, timeout)) {
0062 if ((readl(base + reg) & checkbit) == status)
0063 return 0;
0064 }
0065
0066 return -EFAULT;
0067 }
0068
0069 static int exynos_sata_phy_power_on(struct phy *phy)
0070 {
0071 struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
0072
0073 return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
0074 EXYNOS5_SATAPHY_PMU_ENABLE, true);
0075
0076 }
0077
0078 static int exynos_sata_phy_power_off(struct phy *phy)
0079 {
0080 struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
0081
0082 return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
0083 EXYNOS5_SATAPHY_PMU_ENABLE, false);
0084
0085 }
0086
0087 static int exynos_sata_phy_init(struct phy *phy)
0088 {
0089 u32 val = 0;
0090 int ret = 0;
0091 u8 buf[] = { 0x3a, 0x0b };
0092 struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
0093
0094 ret = regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
0095 EXYNOS5_SATAPHY_PMU_ENABLE, true);
0096 if (ret != 0)
0097 dev_err(&sata_phy->phy->dev, "phy init failed\n");
0098
0099 writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
0100
0101 val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
0102 val |= RESET_GLOBAL_RST_N | RESET_CMN_RST_N | RESET_CMN_BLOCK_RST_N
0103 | RESET_CMN_I2C_RST_N | RESET_TX_RX_PIPE_RST_N
0104 | RESET_TX_RX_BLOCK_RST_N | RESET_TX_RX_I2C_RST_N;
0105 writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
0106
0107 val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
0108 val |= LINK_RESET;
0109 writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
0110
0111 val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
0112 val |= RESET_CMN_RST_N;
0113 writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
0114
0115 val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
0116 val &= ~PHCTRLM_REF_RATE;
0117 writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
0118
0119
0120 val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
0121 val |= PHCTRLM_HIGH_SPEED;
0122 writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
0123
0124 val = readl(sata_phy->regs + EXYNOS5_SATA_CTRL0);
0125 val |= CTRL0_P0_PHY_CALIBRATED_SEL | CTRL0_P0_PHY_CALIBRATED;
0126 writel(val, sata_phy->regs + EXYNOS5_SATA_CTRL0);
0127
0128 val = readl(sata_phy->regs + EXYNOS5_SATA_MODE0);
0129 val |= SATA_SPD_GEN3;
0130 writel(val, sata_phy->regs + EXYNOS5_SATA_MODE0);
0131
0132 ret = i2c_master_send(sata_phy->client, buf, sizeof(buf));
0133 if (ret < 0)
0134 return ret;
0135
0136
0137 val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
0138 val &= ~RESET_CMN_RST_N;
0139 writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
0140
0141 val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
0142 val |= RESET_CMN_RST_N;
0143 writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
0144
0145 ret = wait_for_reg_status(sata_phy->regs,
0146 EXYNOS5_SATA_PHSATA_STATM,
0147 PHSTATM_PLL_LOCKED, 1);
0148 if (ret < 0)
0149 dev_err(&sata_phy->phy->dev,
0150 "PHY PLL locking failed\n");
0151 return ret;
0152 }
0153
0154 static const struct phy_ops exynos_sata_phy_ops = {
0155 .init = exynos_sata_phy_init,
0156 .power_on = exynos_sata_phy_power_on,
0157 .power_off = exynos_sata_phy_power_off,
0158 .owner = THIS_MODULE,
0159 };
0160
0161 static int exynos_sata_phy_probe(struct platform_device *pdev)
0162 {
0163 struct exynos_sata_phy *sata_phy;
0164 struct device *dev = &pdev->dev;
0165 struct phy_provider *phy_provider;
0166 struct device_node *node;
0167 int ret = 0;
0168
0169 sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL);
0170 if (!sata_phy)
0171 return -ENOMEM;
0172
0173 sata_phy->regs = devm_platform_ioremap_resource(pdev, 0);
0174 if (IS_ERR(sata_phy->regs))
0175 return PTR_ERR(sata_phy->regs);
0176
0177 sata_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
0178 "samsung,syscon-phandle");
0179 if (IS_ERR(sata_phy->pmureg)) {
0180 dev_err(dev, "syscon regmap lookup failed.\n");
0181 return PTR_ERR(sata_phy->pmureg);
0182 }
0183
0184 node = of_parse_phandle(dev->of_node,
0185 "samsung,exynos-sataphy-i2c-phandle", 0);
0186 if (!node)
0187 return -EINVAL;
0188
0189 sata_phy->client = of_find_i2c_device_by_node(node);
0190 of_node_put(node);
0191 if (!sata_phy->client)
0192 return -EPROBE_DEFER;
0193
0194 dev_set_drvdata(dev, sata_phy);
0195
0196 sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl");
0197 if (IS_ERR(sata_phy->phyclk)) {
0198 dev_err(dev, "failed to get clk for PHY\n");
0199 ret = PTR_ERR(sata_phy->phyclk);
0200 goto put_dev;
0201 }
0202
0203 ret = clk_prepare_enable(sata_phy->phyclk);
0204 if (ret < 0) {
0205 dev_err(dev, "failed to enable source clk\n");
0206 goto put_dev;
0207 }
0208
0209 sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops);
0210 if (IS_ERR(sata_phy->phy)) {
0211 dev_err(dev, "failed to create PHY\n");
0212 ret = PTR_ERR(sata_phy->phy);
0213 goto clk_disable;
0214 }
0215
0216 phy_set_drvdata(sata_phy->phy, sata_phy);
0217
0218 phy_provider = devm_of_phy_provider_register(dev,
0219 of_phy_simple_xlate);
0220 if (IS_ERR(phy_provider)) {
0221 ret = PTR_ERR(phy_provider);
0222 goto clk_disable;
0223 }
0224
0225 return 0;
0226
0227 clk_disable:
0228 clk_disable_unprepare(sata_phy->phyclk);
0229 put_dev:
0230 put_device(&sata_phy->client->dev);
0231
0232 return ret;
0233 }
0234
0235 static const struct of_device_id exynos_sata_phy_of_match[] = {
0236 { .compatible = "samsung,exynos5250-sata-phy" },
0237 { },
0238 };
0239 MODULE_DEVICE_TABLE(of, exynos_sata_phy_of_match);
0240
0241 static struct platform_driver exynos_sata_phy_driver = {
0242 .probe = exynos_sata_phy_probe,
0243 .driver = {
0244 .of_match_table = exynos_sata_phy_of_match,
0245 .name = "samsung,sata-phy",
0246 .suppress_bind_attrs = true,
0247 }
0248 };
0249 module_platform_driver(exynos_sata_phy_driver);
0250
0251 MODULE_DESCRIPTION("Samsung SerDes PHY driver");
0252 MODULE_LICENSE("GPL v2");
0253 MODULE_AUTHOR("Girish K S <ks.giri@samsung.com>");
0254 MODULE_AUTHOR("Yuvaraj C D <yuvaraj.cd@samsung.com>");