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);