// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2021 Linaro Ltd. * Copyright (C) 2021 Dávid Virág <[email protected]> * Author: Sam Protsenko <[email protected]> * Author: Dávid Virág <[email protected]> * * This file contains shared functions used by some arm64 Exynos SoCs, * such as Exynos7885 or Exynos850 to register and init CMUs. */ #include <linux/clk.h> #include <linux/of_address.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/slab.h> #include "clk-exynos-arm64.h" /* PLL register bits */ #define PLL_CON1_MANUAL … /* Gate register bits */ #define GATE_MANUAL … #define GATE_ENABLE_HWACG … /* PLL_CONx_PLL register offsets range */ #define PLL_CON_OFF_START … #define PLL_CON_OFF_END … /* Gate register offsets range */ #define GATE_OFF_START … #define GATE_OFF_END … struct exynos_arm64_cmu_data { … }; /* Check if the register offset is a GATE register */ static bool is_gate_reg(unsigned long off) { … } /* Check if the register offset is a PLL_CONx register */ static bool is_pll_conx_reg(unsigned long off) { … } /* Check if the register offset is a PLL_CON1 register */ static bool is_pll_con1_reg(unsigned long off) { … } /** * exynos_arm64_init_clocks - Set clocks initial configuration * @np: CMU device tree node with "reg" property (CMU addr) * @cmu: CMU data * * Set manual control mode for all gate and PLL clocks. */ static void __init exynos_arm64_init_clocks(struct device_node *np, const struct samsung_cmu_info *cmu) { … } /** * exynos_arm64_enable_bus_clk - Enable parent clock of specified CMU * * @dev: Device object; may be NULL if this function is not being * called from platform driver probe function * @np: CMU device tree node * @cmu: CMU data * * Keep CMU parent clock running (needed for CMU registers access). * * Return: 0 on success or a negative error code on failure. */ static int __init exynos_arm64_enable_bus_clk(struct device *dev, struct device_node *np, const struct samsung_cmu_info *cmu) { … } static int __init exynos_arm64_cmu_prepare_pm(struct device *dev, const struct samsung_cmu_info *cmu) { … } /** * exynos_arm64_register_cmu - Register specified Exynos CMU domain * @dev: Device object; may be NULL if this function is not being * called from platform driver probe function * @np: CMU device tree node * @cmu: CMU data * * Register specified CMU domain, which includes next steps: * * 1. Enable parent clock of @cmu CMU * 2. Set initial registers configuration for @cmu CMU clocks * 3. Register @cmu CMU clocks using Samsung clock framework API */ void __init exynos_arm64_register_cmu(struct device *dev, struct device_node *np, const struct samsung_cmu_info *cmu) { … } /** * exynos_arm64_register_cmu_pm - Register Exynos CMU domain with PM support * * @pdev: Platform device object * @set_manual: If true, set gate clocks to manual mode * * It's a version of exynos_arm64_register_cmu() with PM support. Should be * called from probe function of platform driver. * * Return: 0 on success, or negative error code on error. */ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev, bool set_manual) { … } int exynos_arm64_cmu_suspend(struct device *dev) { … } int exynos_arm64_cmu_resume(struct device *dev) { … }