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-composite-93.c (2090B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright 2021 NXP
      4 *
      5 * Peng Fan <peng.fan@nxp.com>
      6 */
      7
      8#include <linux/clk-provider.h>
      9#include <linux/errno.h>
     10#include <linux/export.h>
     11#include <linux/io.h>
     12#include <linux/slab.h>
     13
     14#include "clk.h"
     15
     16#define CCM_DIV_SHIFT	0
     17#define CCM_DIV_WIDTH	8
     18#define CCM_MUX_SHIFT	8
     19#define CCM_MUX_MASK	3
     20#define CCM_OFF_SHIFT	24
     21
     22#define AUTHEN_OFFSET	0x30
     23#define TZ_NS_SHIFT	9
     24#define TZ_NS_MASK	BIT(9)
     25
     26struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *parent_names,
     27					 int num_parents, void __iomem *reg,
     28					 unsigned long flags)
     29{
     30	struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw;
     31	struct clk_hw *div_hw, *gate_hw;
     32	struct clk_divider *div = NULL;
     33	struct clk_gate *gate = NULL;
     34	struct clk_mux *mux = NULL;
     35	bool clk_ro = false;
     36
     37	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
     38	if (!mux)
     39		goto fail;
     40
     41	mux_hw = &mux->hw;
     42	mux->reg = reg;
     43	mux->shift = CCM_MUX_SHIFT;
     44	mux->mask = CCM_MUX_MASK;
     45	mux->lock = &imx_ccm_lock;
     46
     47	div = kzalloc(sizeof(*div), GFP_KERNEL);
     48	if (!div)
     49		goto fail;
     50
     51	div_hw = &div->hw;
     52	div->reg = reg;
     53	div->shift = CCM_DIV_SHIFT;
     54	div->width = CCM_DIV_WIDTH;
     55	div->lock = &imx_ccm_lock;
     56	div->flags = CLK_DIVIDER_ROUND_CLOSEST;
     57
     58	if (!(readl(reg + AUTHEN_OFFSET) & TZ_NS_MASK))
     59		clk_ro = true;
     60
     61	if (clk_ro) {
     62		hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
     63					       mux_hw, &clk_mux_ro_ops, div_hw,
     64					       &clk_divider_ro_ops, NULL, NULL, flags);
     65	} else {
     66		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
     67		if (!gate)
     68			goto fail;
     69
     70		gate_hw = &gate->hw;
     71		gate->reg = reg;
     72		gate->bit_idx = CCM_OFF_SHIFT;
     73		gate->lock = &imx_ccm_lock;
     74		gate->flags = CLK_GATE_SET_TO_DISABLE;
     75
     76		hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
     77					       mux_hw, &clk_mux_ops, div_hw,
     78					       &clk_divider_ops, gate_hw,
     79					       &clk_gate_ops, flags | CLK_SET_RATE_NO_REPARENT);
     80	}
     81
     82	if (IS_ERR(hw))
     83		goto fail;
     84
     85	return hw;
     86
     87fail:
     88	kfree(gate);
     89	kfree(div);
     90	kfree(mux);
     91	return ERR_CAST(hw);
     92}
     93EXPORT_SYMBOL_GPL(imx93_clk_composite_flags);