Lines Matching +full:abs +full:- +full:range

1 // SPDX-License-Identifier: GPL-2.0+
10 #include <linux/clk-provider.h>
286 /* PHY_REG(1-7) pix clk specific */
332 u32 pclk = cfg->pixclk; in fsl_samsung_hdmi_phy_configure_pll_lock_det()
345 return -EINVAL; in fsl_samsung_hdmi_phy_configure_pll_lock_det()
347 writeb(FIELD_PREP(REG12_CK_DIV_MASK, div), phy->regs + PHY_REG(12)); in fsl_samsung_hdmi_phy_configure_pll_lock_det()
365 phy->regs + PHY_REG(13)); in fsl_samsung_hdmi_phy_configure_pll_lock_det()
369 phy->regs + PHY_REG(14)); in fsl_samsung_hdmi_phy_configure_pll_lock_det()
383 * Figure 13-78 of the reference manual states the PLL should be TMDS x 5 in fsl_samsung_hdmi_phy_find_pms()
389 /* The ref manual states the values of 'P' range from 1 to 11 */ in fsl_samsung_hdmi_phy_find_pms()
404 * The Ref manual doesn't explicitly state the range of M, in fsl_samsung_hdmi_phy_find_pms()
405 * but it does show it as an 8-bit value, so reject in fsl_samsung_hdmi_phy_find_pms()
416 * VCO can range between 750MHz and in fsl_samsung_hdmi_phy_find_pms()
426 /* Final frequency after post-divider */ in fsl_samsung_hdmi_phy_find_pms()
429 delta = abs(fout - tmp); in fsl_samsung_hdmi_phy_find_pms()
459 phy->cur_cfg = cfg; in fsl_samsung_hdmi_phy_configure()
462 writeb(REG33_FIX_DA, phy->regs + PHY_REG(33)); in fsl_samsung_hdmi_phy_configure()
466 writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg); in fsl_samsung_hdmi_phy_configure()
470 writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4); in fsl_samsung_hdmi_phy_configure()
474 cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21)); in fsl_samsung_hdmi_phy_configure()
478 dev_err(phy->dev, "pixclock too large\n"); in fsl_samsung_hdmi_phy_configure()
482 writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33)); in fsl_samsung_hdmi_phy_configure()
484 ret = readb_poll_timeout(phy->regs + PHY_REG(34), val, in fsl_samsung_hdmi_phy_configure()
487 dev_err(phy->dev, "PLL failed to lock\n"); in fsl_samsung_hdmi_phy_configure()
497 if (!phy->cur_cfg) in phy_clk_recalc_rate()
500 return phy->cur_cfg->pixclk; in phy_clk_recalc_rate()
503 /* Helper function to lookup the available fractional-divider rate */
509 for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--) in fsl_samsung_hdmi_phy_lookup_rate()
514 if (phy_pll_cfg[i].pixclk == rate || i + 1 > ARRAY_SIZE(phy_pll_cfg) - 1) in fsl_samsung_hdmi_phy_lookup_rate()
518 return (abs((long) rate - (long) phy_pll_cfg[i].pixclk) < in fsl_samsung_hdmi_phy_lookup_rate()
519 abs((long) rate - (long) phy_pll_cfg[i+1].pixclk) ? in fsl_samsung_hdmi_phy_lookup_rate()
526 cal_phy->pixclk = rate; in fsl_samsung_hdmi_calculate_phy()
527 cal_phy->pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p); in fsl_samsung_hdmi_calculate_phy()
528 cal_phy->pll_div_regs[1] = m; in fsl_samsung_hdmi_calculate_phy()
529 cal_phy->pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1); in fsl_samsung_hdmi_calculate_phy()
530 /* pll_div_regs 3-6 are fixed and pre-defined already */ in fsl_samsung_hdmi_calculate_phy()
542 /* If the clock is out of range return error instead of searching */ in fsl_samsung_hdmi_phy_find_settings()
548 if (fract_div_phy->pixclk == rate) { in fsl_samsung_hdmi_phy_find_settings()
549 dev_dbg(phy->dev, "fractional divider match = %u\n", fract_div_phy->pixclk); in fsl_samsung_hdmi_phy_find_settings()
557 dev_dbg(phy->dev, "integer divider match = %u\n", calculated_phy_pll_cfg.pixclk); in fsl_samsung_hdmi_phy_find_settings()
562 if (abs((long)rate - (long)int_div_clk) < in fsl_samsung_hdmi_phy_find_settings()
563 abs((long)rate - (long)fract_div_phy->pixclk)) { in fsl_samsung_hdmi_phy_find_settings()
564 dev_dbg(phy->dev, "integer divider = %u\n", calculated_phy_pll_cfg.pixclk); in fsl_samsung_hdmi_phy_find_settings()
568 dev_dbg(phy->dev, "fractional divider = %u\n", phy->cur_cfg->pixclk); in fsl_samsung_hdmi_phy_find_settings()
580 return -EINVAL; in fsl_samsung_hdmi_phy_clk_round_rate()
582 dev_dbg(phy->dev, "round_rate, closest rate = %u\n", target_settings->pixclk); in fsl_samsung_hdmi_phy_clk_round_rate()
583 return target_settings->pixclk; in fsl_samsung_hdmi_phy_clk_round_rate()
593 return -EINVAL; in fsl_samsung_hdmi_phy_clk_set_rate()
595 dev_dbg(phy->dev, "set_rate, closest rate = %u\n", target_settings->pixclk); in fsl_samsung_hdmi_phy_clk_set_rate()
608 struct device *dev = phy->dev; in phy_clk_register()
609 struct device_node *np = dev->of_node; in phy_clk_register()
615 parent_name = __clk_get_name(phy->refclk); in phy_clk_register()
623 phy->hw.init = &init; in phy_clk_register()
625 phyclk = devm_clk_register(dev, &phy->hw); in phy_clk_register()
643 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); in fsl_samsung_hdmi_phy_probe()
645 return -ENOMEM; in fsl_samsung_hdmi_phy_probe()
648 phy->dev = &pdev->dev; in fsl_samsung_hdmi_phy_probe()
650 phy->regs = devm_platform_ioremap_resource(pdev, 0); in fsl_samsung_hdmi_phy_probe()
651 if (IS_ERR(phy->regs)) in fsl_samsung_hdmi_phy_probe()
652 return PTR_ERR(phy->regs); in fsl_samsung_hdmi_phy_probe()
654 phy->apbclk = devm_clk_get_enabled(phy->dev, "apb"); in fsl_samsung_hdmi_phy_probe()
655 if (IS_ERR(phy->apbclk)) in fsl_samsung_hdmi_phy_probe()
656 return dev_err_probe(phy->dev, PTR_ERR(phy->apbclk), in fsl_samsung_hdmi_phy_probe()
659 phy->refclk = devm_clk_get(phy->dev, "ref"); in fsl_samsung_hdmi_phy_probe()
660 if (IS_ERR(phy->refclk)) in fsl_samsung_hdmi_phy_probe()
661 return dev_err_probe(phy->dev, PTR_ERR(phy->refclk), in fsl_samsung_hdmi_phy_probe()
664 pm_runtime_get_noresume(phy->dev); in fsl_samsung_hdmi_phy_probe()
665 pm_runtime_set_active(phy->dev); in fsl_samsung_hdmi_phy_probe()
666 pm_runtime_enable(phy->dev); in fsl_samsung_hdmi_phy_probe()
670 dev_err(&pdev->dev, "register clk failed\n"); in fsl_samsung_hdmi_phy_probe()
674 pm_runtime_put(phy->dev); in fsl_samsung_hdmi_phy_probe()
684 of_clk_del_provider(pdev->dev.of_node); in fsl_samsung_hdmi_phy_remove()
691 clk_disable_unprepare(phy->apbclk); in fsl_samsung_hdmi_phy_suspend()
701 ret = clk_prepare_enable(phy->apbclk); in fsl_samsung_hdmi_phy_resume()
703 dev_err(phy->dev, "failed to enable apbclk\n"); in fsl_samsung_hdmi_phy_resume()
707 if (phy->cur_cfg) in fsl_samsung_hdmi_phy_resume()
708 ret = fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg); in fsl_samsung_hdmi_phy_resume()
720 .compatible = "fsl,imx8mp-hdmi-phy",
731 .name = "fsl-samsung-hdmi-phy",