1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2016 Freescale Semiconductor, Inc.
4 * Copyright 2017~2018 NXP
8 #include <linux/bits.h>
9 #include <linux/clk-provider.h>
10 #include <linux/err.h>
11 #include <linux/slab.h>
15 #define PCG_PCS_SHIFT 24
16 #define PCG_PCS_MASK 0x7
17 #define PCG_CGC_SHIFT 30
18 #define PCG_FRAC_SHIFT 3
19 #define PCG_FRAC_WIDTH 1
20 #define PCG_FRAC_MASK BIT(3)
21 #define PCG_PCD_SHIFT 0
22 #define PCG_PCD_WIDTH 3
23 #define PCG_PCD_MASK 0x7
25 struct clk_hw
*imx7ulp_clk_hw_composite(const char *name
,
26 const char * const *parent_names
,
27 int num_parents
, bool mux_present
,
28 bool rate_present
, bool gate_present
,
31 struct clk_hw
*mux_hw
= NULL
, *fd_hw
= NULL
, *gate_hw
= NULL
;
32 struct clk_fractional_divider
*fd
= NULL
;
33 struct clk_gate
*gate
= NULL
;
34 struct clk_mux
*mux
= NULL
;
38 mux
= kzalloc(sizeof(*mux
), GFP_KERNEL
);
40 return ERR_PTR(-ENOMEM
);
43 mux
->shift
= PCG_PCS_SHIFT
;
44 mux
->mask
= PCG_PCS_MASK
;
48 fd
= kzalloc(sizeof(*fd
), GFP_KERNEL
);
51 return ERR_PTR(-ENOMEM
);
55 fd
->mshift
= PCG_FRAC_SHIFT
;
56 fd
->mwidth
= PCG_FRAC_WIDTH
;
57 fd
->mmask
= PCG_FRAC_MASK
;
58 fd
->nshift
= PCG_PCD_SHIFT
;
59 fd
->nwidth
= PCG_PCD_WIDTH
;
60 fd
->nmask
= PCG_PCD_MASK
;
61 fd
->flags
= CLK_FRAC_DIVIDER_ZERO_BASED
;
65 gate
= kzalloc(sizeof(*gate
), GFP_KERNEL
);
69 return ERR_PTR(-ENOMEM
);
73 gate
->bit_idx
= PCG_CGC_SHIFT
;
76 hw
= clk_hw_register_composite(NULL
, name
, parent_names
, num_parents
,
77 mux_hw
, &clk_mux_ops
, fd_hw
,
78 &clk_fractional_divider_ops
, gate_hw
,
79 &clk_gate_ops
, CLK_SET_RATE_GATE
|