Lines Matching +full:dphy +full:- +full:rx
1 // SPDX-License-Identifier: GPL-2.0
3 * Rockchip MIPI RX Innosilicon DPHY driver
17 #include <linux/phy/phy-mipi-dphy.h>
62 /* Configure the count time of the THS-SETTLE by protocol. */
75 * The higher 16-bit of this register is used for write protection
98 { .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, .valid = 1, }
159 const struct dphy_drv_data *drv_data = priv->drv_data; in write_grf_reg()
160 const struct dphy_reg *reg = &drv_data->grf_regs[index]; in write_grf_reg()
162 if (reg->valid) in write_grf_reg()
163 regmap_write(priv->grf, reg->offset, in write_grf_reg()
164 HIWORD_UPDATE(value, reg->mask, reg->shift)); in write_grf_reg()
202 const struct dphy_drv_data *drv_data = priv->drv_data; in rockchip_inno_csidphy_ths_settle()
205 val = readl(priv->phy_base + drv_data->ths_settle_offset + offset); in rockchip_inno_csidphy_ths_settle()
208 writel(val, priv->phy_base + drv_data->ths_settle_offset + offset); in rockchip_inno_csidphy_ths_settle()
215 const struct dphy_drv_data *drv_data = priv->drv_data; in rockchip_inno_csidphy_configure()
216 struct phy_configure_opts_mipi_dphy *config = &opts->mipi_dphy; in rockchip_inno_csidphy_configure()
227 data_rate_mbps = HZ_TO_MHZ(config->hs_clk_rate); in rockchip_inno_csidphy_configure()
229 dev_dbg(priv->dev, "lanes %d - data_rate_mbps %llu\n", in rockchip_inno_csidphy_configure()
230 config->lanes, data_rate_mbps); in rockchip_inno_csidphy_configure()
231 for (i = 0; i < drv_data->num_hsfreq_ranges; i++) { in rockchip_inno_csidphy_configure()
232 if (drv_data->hsfreq_ranges[i].range_h >= data_rate_mbps) { in rockchip_inno_csidphy_configure()
233 hsfreq = drv_data->hsfreq_ranges[i].cfg_bit; in rockchip_inno_csidphy_configure()
238 return -EINVAL; in rockchip_inno_csidphy_configure()
240 priv->hsfreq = hsfreq; in rockchip_inno_csidphy_configure()
241 priv->config = *config; in rockchip_inno_csidphy_configure()
248 const struct dphy_drv_data *drv_data = priv->drv_data; in rockchip_inno_csidphy_power_on()
249 u64 data_rate_mbps = HZ_TO_MHZ(priv->config.hs_clk_rate); in rockchip_inno_csidphy_power_on()
253 ret = clk_enable(priv->pclk); in rockchip_inno_csidphy_power_on()
257 ret = pm_runtime_resume_and_get(priv->dev); in rockchip_inno_csidphy_power_on()
259 clk_disable(priv->pclk); in rockchip_inno_csidphy_power_on()
264 if (drv_data->pwrctl_offset >= 0) in rockchip_inno_csidphy_power_on()
267 priv->phy_base + drv_data->pwrctl_offset); in rockchip_inno_csidphy_power_on()
270 val = FIELD_PREP(CSIDPHY_CTRL_LANE_ENABLE_MASK, GENMASK(priv->config.lanes - 1, 0)) | in rockchip_inno_csidphy_power_on()
273 writel(val, priv->phy_base + CSIDPHY_CTRL_LANE_ENABLE); in rockchip_inno_csidphy_power_on()
275 /* Reset dphy analog part */ in rockchip_inno_csidphy_power_on()
276 if (drv_data->pwrctl_offset >= 0) in rockchip_inno_csidphy_power_on()
278 priv->phy_base + drv_data->pwrctl_offset); in rockchip_inno_csidphy_power_on()
281 /* Reset dphy digital part */ in rockchip_inno_csidphy_power_on()
283 priv->phy_base + CSIDPHY_CTRL_DIG_RST); in rockchip_inno_csidphy_power_on()
285 priv->phy_base + CSIDPHY_CTRL_DIG_RST); in rockchip_inno_csidphy_power_on()
291 if (data_rate_mbps > 1500 && drv_data->calib_offset >= 0) { in rockchip_inno_csidphy_power_on()
293 priv->phy_base + drv_data->calib_offset + in rockchip_inno_csidphy_power_on()
295 for (i = 0; i < priv->config.lanes; i++) in rockchip_inno_csidphy_power_on()
297 priv->phy_base + drv_data->calib_offset + in rockchip_inno_csidphy_power_on()
301 rockchip_inno_csidphy_ths_settle(priv, priv->hsfreq, in rockchip_inno_csidphy_power_on()
303 for (i = 0; i < priv->config.lanes; i++) in rockchip_inno_csidphy_power_on()
304 rockchip_inno_csidphy_ths_settle(priv, priv->hsfreq, in rockchip_inno_csidphy_power_on()
309 GENMASK(priv->config.lanes - 1, 0)); in rockchip_inno_csidphy_power_on()
317 const struct dphy_drv_data *drv_data = priv->drv_data; in rockchip_inno_csidphy_power_off()
321 priv->phy_base + CSIDPHY_CTRL_LANE_ENABLE); in rockchip_inno_csidphy_power_off()
324 if (drv_data->pwrctl_offset >= 0) in rockchip_inno_csidphy_power_off()
328 priv->phy_base + drv_data->pwrctl_offset); in rockchip_inno_csidphy_power_off()
331 pm_runtime_put(priv->dev); in rockchip_inno_csidphy_power_off()
332 clk_disable(priv->pclk); in rockchip_inno_csidphy_power_off()
341 return clk_prepare(priv->pclk); in rockchip_inno_csidphy_init()
348 clk_unprepare(priv->pclk); in rockchip_inno_csidphy_exit()
363 .pwrctl_offset = -1,
376 .calib_offset = -1,
387 .calib_offset = -1,
396 .pwrctl_offset = -1,
407 .pwrctl_offset = -1,
419 .compatible = "rockchip,px30-csi-dphy",
423 .compatible = "rockchip,rk1808-csi-dphy",
427 .compatible = "rockchip,rk3326-csi-dphy",
431 .compatible = "rockchip,rk3368-csi-dphy",
435 .compatible = "rockchip,rk3568-csi-dphy",
439 .compatible = "rockchip,rk3588-csi-dphy",
449 struct device *dev = &pdev->dev; in rockchip_inno_csidphy_probe()
456 return -ENOMEM; in rockchip_inno_csidphy_probe()
458 priv->dev = dev; in rockchip_inno_csidphy_probe()
461 priv->drv_data = of_device_get_match_data(dev); in rockchip_inno_csidphy_probe()
462 if (!priv->drv_data) { in rockchip_inno_csidphy_probe()
464 return -ENODEV; in rockchip_inno_csidphy_probe()
467 priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, in rockchip_inno_csidphy_probe()
469 if (IS_ERR(priv->grf)) { in rockchip_inno_csidphy_probe()
471 return PTR_ERR(priv->grf); in rockchip_inno_csidphy_probe()
474 priv->phy_base = devm_platform_ioremap_resource(pdev, 0); in rockchip_inno_csidphy_probe()
475 if (IS_ERR(priv->phy_base)) in rockchip_inno_csidphy_probe()
476 return PTR_ERR(priv->phy_base); in rockchip_inno_csidphy_probe()
478 priv->pclk = devm_clk_get(dev, "pclk"); in rockchip_inno_csidphy_probe()
479 if (IS_ERR(priv->pclk)) { in rockchip_inno_csidphy_probe()
481 return PTR_ERR(priv->pclk); in rockchip_inno_csidphy_probe()
484 if (priv->drv_data->resets_num > RESETS_MAX) { in rockchip_inno_csidphy_probe()
486 return -EINVAL; in rockchip_inno_csidphy_probe()
488 priv->resets_num = priv->drv_data->resets_num; in rockchip_inno_csidphy_probe()
489 for (unsigned int i = 0; i < priv->resets_num; i++) in rockchip_inno_csidphy_probe()
490 priv->resets[i].id = priv->drv_data->resets[i]; in rockchip_inno_csidphy_probe()
491 ret = devm_reset_control_bulk_get_exclusive(dev, priv->resets_num, in rockchip_inno_csidphy_probe()
492 priv->resets); in rockchip_inno_csidphy_probe()
521 pm_runtime_disable(priv->dev); in rockchip_inno_csidphy_remove()
526 .name = "rockchip-inno-csidphy",
534 MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@theobroma-systems.com>");
535 MODULE_DESCRIPTION("Rockchip MIPI Innosilicon CSI-DPHY driver");