Lines Matching +full:mpfs +full:- +full:mss +full:- +full:top +full:- +full:sysreg

1 // SPDX-License-Identifier: GPL-2.0-only
3 * PolarFire SoC MSS/core complex clock control
5 * Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved.
8 #include <linux/clk-provider.h>
14 #include <dt-bindings/clock/microchip,mpfs-clock.h>
15 #include <soc/microchip/mpfs.h>
144 * MSS PLL internal clock
150 void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset; in mpfs_clk_msspll_recalc_rate()
151 void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR; in mpfs_clk_msspll_recalc_rate()
189 msspll_hw->base = data->msspll_base; in mpfs_clk_register_mssplls()
190 ret = devm_clk_hw_register(dev, &msspll_hw->hw); in mpfs_clk_register_mssplls()
195 data->hw_data.hws[msspll_hw->id] = &msspll_hw->hw; in mpfs_clk_register_mssplls()
202 * MSS PLL output clocks
237 msspll_out_hw->output.reg = data->msspll_base + msspll_out_hw->reg_offset; in mpfs_clk_register_msspll_outs()
238 ret = devm_clk_hw_register(dev, &msspll_out_hw->output.hw); in mpfs_clk_register_msspll_outs()
241 msspll_out_hw->id); in mpfs_clk_register_msspll_outs()
243 data->hw_data.hws[msspll_out_hw->id] = &msspll_out_hw->output.hw; in mpfs_clk_register_msspll_outs()
255 struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; in mpfs_cfg_clk_recalc_rate()
258 regmap_read(cfg->map, cfg->map_offset, &val); in mpfs_cfg_clk_recalc_rate()
259 val >>= cfg->shift; in mpfs_cfg_clk_recalc_rate()
260 val &= clk_div_mask(cfg->width); in mpfs_cfg_clk_recalc_rate()
262 return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width); in mpfs_cfg_clk_recalc_rate()
268 struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; in mpfs_cfg_clk_determine_rate()
270 return divider_determine_rate(hw, req, cfg->table, cfg->width, 0); in mpfs_cfg_clk_determine_rate()
276 struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; in mpfs_cfg_clk_set_rate()
281 divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0); in mpfs_cfg_clk_set_rate()
286 mask = clk_div_mask(cfg->width) << cfg->shift; in mpfs_cfg_clk_set_rate()
287 val = divider_setting << cfg->shift; in mpfs_cfg_clk_set_rate()
288 regmap_update_bits(cfg->map, cfg->map_offset, val, mask); in mpfs_cfg_clk_set_rate()
342 cfg_hw->cfg.map = data->regmap; in mpfs_clk_register_cfgs()
343 ret = devm_clk_hw_register(dev, &cfg_hw->hw); in mpfs_clk_register_cfgs()
346 cfg_hw->id); in mpfs_clk_register_cfgs()
348 id = cfg_hw->id; in mpfs_clk_register_cfgs()
349 data->hw_data.hws[id] = &cfg_hw->hw; in mpfs_clk_register_cfgs()
356 * peripheral clocks - devices connected to axi or ahb buses.
362 struct mpfs_periph_clock *periph = &periph_hw->periph; in mpfs_periph_clk_enable()
364 regmap_update_bits(periph->map, periph->map_offset, in mpfs_periph_clk_enable()
365 BIT(periph->shift), BIT(periph->shift)); in mpfs_periph_clk_enable()
373 struct mpfs_periph_clock *periph = &periph_hw->periph; in mpfs_periph_clk_disable()
375 regmap_update_bits(periph->map, periph->map_offset, BIT(periph->shift), 0); in mpfs_periph_clk_disable()
381 struct mpfs_periph_clock *periph = &periph_hw->periph; in mpfs_periph_clk_is_enabled()
384 regmap_read(periph->map, periph->map_offset, &val); in mpfs_periph_clk_is_enabled()
386 return !!(val & BIT(periph->shift)); in mpfs_periph_clk_is_enabled()
406 * - CLK_ENVM: reserved by hart software services (hss) superloop monitor/m mode interrupt
408 * - CLK_MMUART0: reserved by the hss
409 * - CLK_DDRC: provides clock to the ddr subsystem
410 * - CLK_RTC: the onboard RTC's AHB bus clock must be kept running as the rtc will stop
412 * - CLK_FICx: these provide the processor side clocks to the "FIC" (Fabric InterConnect)
415 * - CLK_ATHENA: The athena clock is FIC4, which is reserved for the Athena TeraFire.
459 periph_hw->periph.map = data->regmap; in mpfs_clk_register_periphs()
460 ret = devm_clk_hw_register(dev, &periph_hw->hw); in mpfs_clk_register_periphs()
463 periph_hw->id); in mpfs_clk_register_periphs()
466 data->hw_data.hws[id] = &periph_hw->hw; in mpfs_clk_register_periphs()
475 clk_data->regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-mss-top-sysreg"); in mpfs_clk_syscon_probe()
476 if (IS_ERR(clk_data->regmap)) in mpfs_clk_syscon_probe()
477 return PTR_ERR(clk_data->regmap); in mpfs_clk_syscon_probe()
479 clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 0); in mpfs_clk_syscon_probe()
480 if (IS_ERR(clk_data->msspll_base)) in mpfs_clk_syscon_probe()
481 return PTR_ERR(clk_data->msspll_base); in mpfs_clk_syscon_probe()
489 struct device *dev = &pdev->dev; in mpfs_clk_old_format_probe()
491 dev_warn(&pdev->dev, "falling back to old devicetree format"); in mpfs_clk_old_format_probe()
493 clk_data->base = devm_platform_ioremap_resource(pdev, 0); in mpfs_clk_old_format_probe()
494 if (IS_ERR(clk_data->base)) in mpfs_clk_old_format_probe()
495 return PTR_ERR(clk_data->base); in mpfs_clk_old_format_probe()
497 clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1); in mpfs_clk_old_format_probe()
498 if (IS_ERR(clk_data->msspll_base)) in mpfs_clk_old_format_probe()
499 return PTR_ERR(clk_data->msspll_base); in mpfs_clk_old_format_probe()
501 clk_data->regmap = devm_regmap_init_mmio(dev, clk_data->base, &mpfs_clk_regmap_config); in mpfs_clk_old_format_probe()
502 if (IS_ERR(clk_data->regmap)) in mpfs_clk_old_format_probe()
503 return PTR_ERR(clk_data->regmap); in mpfs_clk_old_format_probe()
505 return mpfs_reset_controller_register(dev, clk_data->regmap); in mpfs_clk_old_format_probe()
510 struct device *dev = &pdev->dev; in mpfs_clk_probe()
521 return -ENOMEM; in mpfs_clk_probe()
530 clk_data->hw_data.num = num_clks; in mpfs_clk_probe()
531 clk_data->dev = dev; in mpfs_clk_probe()
554 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data); in mpfs_clk_probe()
558 { .compatible = "microchip,mpfs-clkcfg", },
566 .name = "microchip-mpfs-clkcfg",