cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

clk-gate-zynqmp.c (3399B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Zynq UltraScale+ MPSoC clock controller
      4 *
      5 *  Copyright (C) 2016-2018 Xilinx
      6 *
      7 * Gated clock implementation
      8 */
      9
     10#include <linux/clk-provider.h>
     11#include <linux/slab.h>
     12#include "clk-zynqmp.h"
     13
     14/**
     15 * struct zynqmp_clk_gate - gating clock
     16 * @hw:		handle between common and hardware-specific interfaces
     17 * @flags:	hardware-specific flags
     18 * @clk_id:	Id of clock
     19 */
     20struct zynqmp_clk_gate {
     21	struct clk_hw hw;
     22	u8 flags;
     23	u32 clk_id;
     24};
     25
     26#define to_zynqmp_clk_gate(_hw) container_of(_hw, struct zynqmp_clk_gate, hw)
     27
     28/**
     29 * zynqmp_clk_gate_enable() - Enable clock
     30 * @hw:		handle between common and hardware-specific interfaces
     31 *
     32 * Return: 0 on success else error code
     33 */
     34static int zynqmp_clk_gate_enable(struct clk_hw *hw)
     35{
     36	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
     37	const char *clk_name = clk_hw_get_name(hw);
     38	u32 clk_id = gate->clk_id;
     39	int ret;
     40
     41	ret = zynqmp_pm_clock_enable(clk_id);
     42
     43	if (ret)
     44		pr_debug("%s() clock enable failed for %s (id %d), ret = %d\n",
     45			 __func__, clk_name, clk_id, ret);
     46
     47	return ret;
     48}
     49
     50/*
     51 * zynqmp_clk_gate_disable() - Disable clock
     52 * @hw:		handle between common and hardware-specific interfaces
     53 */
     54static void zynqmp_clk_gate_disable(struct clk_hw *hw)
     55{
     56	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
     57	const char *clk_name = clk_hw_get_name(hw);
     58	u32 clk_id = gate->clk_id;
     59	int ret;
     60
     61	ret = zynqmp_pm_clock_disable(clk_id);
     62
     63	if (ret)
     64		pr_debug("%s() clock disable failed for %s (id %d), ret = %d\n",
     65			 __func__, clk_name, clk_id, ret);
     66}
     67
     68/**
     69 * zynqmp_clk_gate_is_enabled() - Check clock state
     70 * @hw:		handle between common and hardware-specific interfaces
     71 *
     72 * Return: 1 if enabled, 0 if disabled else error code
     73 */
     74static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
     75{
     76	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
     77	const char *clk_name = clk_hw_get_name(hw);
     78	u32 clk_id = gate->clk_id;
     79	int state, ret;
     80
     81	ret = zynqmp_pm_clock_getstate(clk_id, &state);
     82	if (ret) {
     83		pr_debug("%s() clock get state failed for %s, ret = %d\n",
     84			 __func__, clk_name, ret);
     85		return -EIO;
     86	}
     87
     88	return state ? 1 : 0;
     89}
     90
     91static const struct clk_ops zynqmp_clk_gate_ops = {
     92	.enable = zynqmp_clk_gate_enable,
     93	.disable = zynqmp_clk_gate_disable,
     94	.is_enabled = zynqmp_clk_gate_is_enabled,
     95};
     96
     97/**
     98 * zynqmp_clk_register_gate() - Register a gate clock with the clock framework
     99 * @name:		Name of this clock
    100 * @clk_id:		Id of this clock
    101 * @parents:		Name of this clock's parents
    102 * @num_parents:	Number of parents
    103 * @nodes:		Clock topology node
    104 *
    105 * Return: clock hardware of the registered clock gate
    106 */
    107struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,
    108					const char * const *parents,
    109					u8 num_parents,
    110					const struct clock_topology *nodes)
    111{
    112	struct zynqmp_clk_gate *gate;
    113	struct clk_hw *hw;
    114	int ret;
    115	struct clk_init_data init;
    116
    117	/* allocate the gate */
    118	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
    119	if (!gate)
    120		return ERR_PTR(-ENOMEM);
    121
    122	init.name = name;
    123	init.ops = &zynqmp_clk_gate_ops;
    124
    125	init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);
    126
    127	init.parent_names = parents;
    128	init.num_parents = 1;
    129
    130	/* struct clk_gate assignments */
    131	gate->flags = nodes->type_flag;
    132	gate->hw.init = &init;
    133	gate->clk_id = clk_id;
    134
    135	hw = &gate->hw;
    136	ret = clk_hw_register(NULL, hw);
    137	if (ret) {
    138		kfree(gate);
    139		hw = ERR_PTR(ret);
    140	}
    141
    142	return hw;
    143}