0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/clk.h>
0019 #include <linux/delay.h>
0020 #include <linux/io.h>
0021 #include <linux/mfd/syscon.h>
0022 #include <linux/module.h>
0023 #include <linux/of.h>
0024 #include <linux/of_device.h>
0025 #include <linux/phy/phy.h>
0026 #include <linux/phy/phy-mipi-dphy.h>
0027 #include <linux/platform_device.h>
0028 #include <linux/regmap.h>
0029
0030 #define RK3399_GRF_SOC_CON9 0x6224
0031 #define RK3399_GRF_SOC_CON21 0x6254
0032 #define RK3399_GRF_SOC_CON22 0x6258
0033 #define RK3399_GRF_SOC_CON23 0x625c
0034 #define RK3399_GRF_SOC_CON24 0x6260
0035 #define RK3399_GRF_SOC_CON25 0x6264
0036 #define RK3399_GRF_SOC_STATUS1 0xe2a4
0037
0038 #define CLOCK_LANE_HS_RX_CONTROL 0x34
0039 #define LANE0_HS_RX_CONTROL 0x44
0040 #define LANE1_HS_RX_CONTROL 0x54
0041 #define LANE2_HS_RX_CONTROL 0x84
0042 #define LANE3_HS_RX_CONTROL 0x94
0043 #define LANES_THS_SETTLE_CONTROL 0x75
0044 #define THS_SETTLE_COUNTER_THRESHOLD 0x04
0045
0046 struct hsfreq_range {
0047 u16 range_h;
0048 u8 cfg_bit;
0049 };
0050
0051 static const struct hsfreq_range rk3399_mipidphy_hsfreq_ranges[] = {
0052 { 89, 0x00 }, { 99, 0x10 }, { 109, 0x20 }, { 129, 0x01 },
0053 { 139, 0x11 }, { 149, 0x21 }, { 169, 0x02 }, { 179, 0x12 },
0054 { 199, 0x22 }, { 219, 0x03 }, { 239, 0x13 }, { 249, 0x23 },
0055 { 269, 0x04 }, { 299, 0x14 }, { 329, 0x05 }, { 359, 0x15 },
0056 { 399, 0x25 }, { 449, 0x06 }, { 499, 0x16 }, { 549, 0x07 },
0057 { 599, 0x17 }, { 649, 0x08 }, { 699, 0x18 }, { 749, 0x09 },
0058 { 799, 0x19 }, { 849, 0x29 }, { 899, 0x39 }, { 949, 0x0a },
0059 { 999, 0x1a }, { 1049, 0x2a }, { 1099, 0x3a }, { 1149, 0x0b },
0060 { 1199, 0x1b }, { 1249, 0x2b }, { 1299, 0x3b }, { 1349, 0x0c },
0061 { 1399, 0x1c }, { 1449, 0x2c }, { 1500, 0x3c }
0062 };
0063
0064 static const char * const rk3399_mipidphy_clks[] = {
0065 "dphy-ref",
0066 "dphy-cfg",
0067 "grf",
0068 };
0069
0070 enum dphy_reg_id {
0071 GRF_DPHY_RX0_TURNDISABLE = 0,
0072 GRF_DPHY_RX0_FORCERXMODE,
0073 GRF_DPHY_RX0_FORCETXSTOPMODE,
0074 GRF_DPHY_RX0_ENABLE,
0075 GRF_DPHY_RX0_TESTCLR,
0076 GRF_DPHY_RX0_TESTCLK,
0077 GRF_DPHY_RX0_TESTEN,
0078 GRF_DPHY_RX0_TESTDIN,
0079 GRF_DPHY_RX0_TURNREQUEST,
0080 GRF_DPHY_RX0_TESTDOUT,
0081 GRF_DPHY_TX0_TURNDISABLE,
0082 GRF_DPHY_TX0_FORCERXMODE,
0083 GRF_DPHY_TX0_FORCETXSTOPMODE,
0084 GRF_DPHY_TX0_TURNREQUEST,
0085 GRF_DPHY_TX1RX1_TURNDISABLE,
0086 GRF_DPHY_TX1RX1_FORCERXMODE,
0087 GRF_DPHY_TX1RX1_FORCETXSTOPMODE,
0088 GRF_DPHY_TX1RX1_ENABLE,
0089 GRF_DPHY_TX1RX1_MASTERSLAVEZ,
0090 GRF_DPHY_TX1RX1_BASEDIR,
0091 GRF_DPHY_TX1RX1_ENABLECLK,
0092 GRF_DPHY_TX1RX1_TURNREQUEST,
0093 GRF_DPHY_RX1_SRC_SEL,
0094
0095 GRF_CON_DISABLE_ISP,
0096 GRF_CON_ISP_DPHY_SEL,
0097 GRF_DSI_CSI_TESTBUS_SEL,
0098 GRF_DVP_V18SEL,
0099
0100 GRF_DPHY_RX0_CLK_INV_SEL,
0101 GRF_DPHY_RX1_CLK_INV_SEL,
0102 };
0103
0104 struct dphy_reg {
0105 u16 offset;
0106 u8 mask;
0107 u8 shift;
0108 };
0109
0110 #define PHY_REG(_offset, _width, _shift) \
0111 { .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, }
0112
0113 static const struct dphy_reg rk3399_grf_dphy_regs[] = {
0114 [GRF_DPHY_RX0_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON9, 4, 0),
0115 [GRF_DPHY_RX0_CLK_INV_SEL] = PHY_REG(RK3399_GRF_SOC_CON9, 1, 10),
0116 [GRF_DPHY_RX1_CLK_INV_SEL] = PHY_REG(RK3399_GRF_SOC_CON9, 1, 11),
0117 [GRF_DPHY_RX0_ENABLE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 0),
0118 [GRF_DPHY_RX0_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 4),
0119 [GRF_DPHY_RX0_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 8),
0120 [GRF_DPHY_RX0_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 12),
0121 [GRF_DPHY_TX0_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 0),
0122 [GRF_DPHY_TX0_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 4),
0123 [GRF_DPHY_TX0_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 8),
0124 [GRF_DPHY_TX0_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 12),
0125 [GRF_DPHY_TX1RX1_ENABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 0),
0126 [GRF_DPHY_TX1RX1_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 4),
0127 [GRF_DPHY_TX1RX1_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 8),
0128 [GRF_DPHY_TX1RX1_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 12),
0129 [GRF_DPHY_TX1RX1_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON24, 4, 0),
0130 [GRF_DPHY_RX1_SRC_SEL] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 4),
0131 [GRF_DPHY_TX1RX1_BASEDIR] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 5),
0132 [GRF_DPHY_TX1RX1_ENABLECLK] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 6),
0133 [GRF_DPHY_TX1RX1_MASTERSLAVEZ] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 7),
0134 [GRF_DPHY_RX0_TESTDIN] = PHY_REG(RK3399_GRF_SOC_CON25, 8, 0),
0135 [GRF_DPHY_RX0_TESTEN] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 8),
0136 [GRF_DPHY_RX0_TESTCLK] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 9),
0137 [GRF_DPHY_RX0_TESTCLR] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 10),
0138 [GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
0139 };
0140
0141 struct rk_dphy_drv_data {
0142 const char * const *clks;
0143 unsigned int num_clks;
0144 const struct hsfreq_range *hsfreq_ranges;
0145 unsigned int num_hsfreq_ranges;
0146 const struct dphy_reg *regs;
0147 };
0148
0149 struct rk_dphy {
0150 struct device *dev;
0151 struct regmap *grf;
0152 struct clk_bulk_data *clks;
0153
0154 const struct rk_dphy_drv_data *drv_data;
0155 struct phy_configure_opts_mipi_dphy config;
0156
0157 u8 hsfreq;
0158 };
0159
0160 static inline void rk_dphy_write_grf(struct rk_dphy *priv,
0161 unsigned int index, u8 value)
0162 {
0163 const struct dphy_reg *reg = &priv->drv_data->regs[index];
0164
0165 unsigned int val = (value << reg->shift) |
0166 (reg->mask << (reg->shift + 16));
0167
0168 if (WARN_ON(!reg->offset))
0169 return;
0170 regmap_write(priv->grf, reg->offset, val);
0171 }
0172
0173 static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
0174 {
0175 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTDIN, test_code);
0176 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTEN, 1);
0177
0178
0179
0180
0181
0182
0183 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 0);
0184 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTEN, 0);
0185 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTDIN, test_data);
0186 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 1);
0187 }
0188
0189 static void rk_dphy_enable(struct rk_dphy *priv)
0190 {
0191 rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCERXMODE, 0);
0192 rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCETXSTOPMODE, 0);
0193
0194
0195 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TURNREQUEST, 0);
0196 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TURNDISABLE, 0xf);
0197
0198 rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE,
0199 GENMASK(priv->config.lanes - 1, 0));
0200
0201
0202 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 1);
0203 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLR, 1);
0204 usleep_range(100, 150);
0205 rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLR, 0);
0206 usleep_range(100, 150);
0207
0208
0209
0210 rk_dphy_write(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
0211
0212 rk_dphy_write(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
0213
0214 rk_dphy_write(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
0215
0216 rk_dphy_write(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
0217
0218 rk_dphy_write(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
0219
0220 rk_dphy_write(priv, LANES_THS_SETTLE_CONTROL,
0221 THS_SETTLE_COUNTER_THRESHOLD);
0222
0223
0224 rk_dphy_write(priv, 0x0, 0);
0225 }
0226
0227 static int rk_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
0228 {
0229 struct rk_dphy *priv = phy_get_drvdata(phy);
0230 const struct rk_dphy_drv_data *drv_data = priv->drv_data;
0231 struct phy_configure_opts_mipi_dphy *config = &opts->mipi_dphy;
0232 unsigned int hsfreq = 0;
0233 unsigned int i;
0234 u64 data_rate_mbps;
0235 int ret;
0236
0237
0238 ret = phy_mipi_dphy_config_validate(config);
0239 if (ret)
0240 return ret;
0241
0242 data_rate_mbps = div_u64(config->hs_clk_rate, 1000 * 1000);
0243
0244 dev_dbg(priv->dev, "lanes %d - data_rate_mbps %llu\n",
0245 config->lanes, data_rate_mbps);
0246 for (i = 0; i < drv_data->num_hsfreq_ranges; i++) {
0247 if (drv_data->hsfreq_ranges[i].range_h >= data_rate_mbps) {
0248 hsfreq = drv_data->hsfreq_ranges[i].cfg_bit;
0249 break;
0250 }
0251 }
0252 if (!hsfreq)
0253 return -EINVAL;
0254
0255 priv->hsfreq = hsfreq;
0256 priv->config = *config;
0257 return 0;
0258 }
0259
0260 static int rk_dphy_power_on(struct phy *phy)
0261 {
0262 struct rk_dphy *priv = phy_get_drvdata(phy);
0263 int ret;
0264
0265 ret = clk_bulk_enable(priv->drv_data->num_clks, priv->clks);
0266 if (ret)
0267 return ret;
0268
0269 rk_dphy_enable(priv);
0270
0271 return 0;
0272 }
0273
0274 static int rk_dphy_power_off(struct phy *phy)
0275 {
0276 struct rk_dphy *priv = phy_get_drvdata(phy);
0277
0278 rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
0279 clk_bulk_disable(priv->drv_data->num_clks, priv->clks);
0280 return 0;
0281 }
0282
0283 static int rk_dphy_init(struct phy *phy)
0284 {
0285 struct rk_dphy *priv = phy_get_drvdata(phy);
0286
0287 return clk_bulk_prepare(priv->drv_data->num_clks, priv->clks);
0288 }
0289
0290 static int rk_dphy_exit(struct phy *phy)
0291 {
0292 struct rk_dphy *priv = phy_get_drvdata(phy);
0293
0294 clk_bulk_unprepare(priv->drv_data->num_clks, priv->clks);
0295 return 0;
0296 }
0297
0298 static const struct phy_ops rk_dphy_ops = {
0299 .power_on = rk_dphy_power_on,
0300 .power_off = rk_dphy_power_off,
0301 .init = rk_dphy_init,
0302 .exit = rk_dphy_exit,
0303 .configure = rk_dphy_configure,
0304 .owner = THIS_MODULE,
0305 };
0306
0307 static const struct rk_dphy_drv_data rk3399_mipidphy_drv_data = {
0308 .clks = rk3399_mipidphy_clks,
0309 .num_clks = ARRAY_SIZE(rk3399_mipidphy_clks),
0310 .hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
0311 .num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
0312 .regs = rk3399_grf_dphy_regs,
0313 };
0314
0315 static const struct of_device_id rk_dphy_dt_ids[] = {
0316 {
0317 .compatible = "rockchip,rk3399-mipi-dphy-rx0",
0318 .data = &rk3399_mipidphy_drv_data,
0319 },
0320 {}
0321 };
0322 MODULE_DEVICE_TABLE(of, rk_dphy_dt_ids);
0323
0324 static int rk_dphy_probe(struct platform_device *pdev)
0325 {
0326 struct device *dev = &pdev->dev;
0327 struct device_node *np = dev->of_node;
0328 const struct rk_dphy_drv_data *drv_data;
0329 struct phy_provider *phy_provider;
0330 struct rk_dphy *priv;
0331 struct phy *phy;
0332 unsigned int i;
0333 int ret;
0334
0335 if (!dev->parent || !dev->parent->of_node)
0336 return -ENODEV;
0337
0338 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0339 if (!priv)
0340 return -ENOMEM;
0341 priv->dev = dev;
0342
0343 priv->grf = syscon_node_to_regmap(dev->parent->of_node);
0344 if (IS_ERR(priv->grf)) {
0345 dev_err(dev, "Can't find GRF syscon\n");
0346 return -ENODEV;
0347 }
0348
0349 drv_data = of_device_get_match_data(dev);
0350 priv->drv_data = drv_data;
0351 priv->clks = devm_kcalloc(&pdev->dev, drv_data->num_clks,
0352 sizeof(*priv->clks), GFP_KERNEL);
0353 if (!priv->clks)
0354 return -ENOMEM;
0355 for (i = 0; i < drv_data->num_clks; i++)
0356 priv->clks[i].id = drv_data->clks[i];
0357 ret = devm_clk_bulk_get(&pdev->dev, drv_data->num_clks, priv->clks);
0358 if (ret)
0359 return ret;
0360
0361 phy = devm_phy_create(dev, np, &rk_dphy_ops);
0362 if (IS_ERR(phy)) {
0363 dev_err(dev, "failed to create phy\n");
0364 return PTR_ERR(phy);
0365 }
0366 phy_set_drvdata(phy, priv);
0367
0368 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0369
0370 return PTR_ERR_OR_ZERO(phy_provider);
0371 }
0372
0373 static struct platform_driver rk_dphy_driver = {
0374 .probe = rk_dphy_probe,
0375 .driver = {
0376 .name = "rockchip-mipi-dphy-rx0",
0377 .of_match_table = rk_dphy_dt_ids,
0378 },
0379 };
0380 module_platform_driver(rk_dphy_driver);
0381
0382 MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
0383 MODULE_DESCRIPTION("Rockchip MIPI Synopsys DPHY RX0 driver");
0384 MODULE_LICENSE("Dual MIT/GPL");