Home | History | Annotate | Line # | Download | only in nxp
      1 /*	$NetBSD: imx6_ccmvar.h,v 1.3 2023/05/04 13:25:07 bouyer Exp $	*/
      2 /*
      3  * Copyright (c) 2012,2019  Genetec Corporation.  All rights reserved.
      4  * Written by Hashimoto Kenichi for Genetec Corporation.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
     16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
     19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #ifndef	_ARM_NXP_IMX6_CCMVAR_H_
     29 #define	_ARM_NXP_IMX6_CCMVAR_H_
     30 
     31 #include <dev/clk/clk.h>
     32 #include <dev/clk/clk_backend.h>
     33 
     34 struct imx6ccm_softc {
     35 	device_t sc_dev;
     36 	bus_space_tag_t sc_iot;
     37 	bus_space_handle_t sc_ioh;
     38 	bus_space_handle_t sc_ioh_analog;
     39 
     40 	struct clk_domain sc_clkdom;
     41 	struct imx6_clk *sc_imx6_clks;
     42 	int sc_imx6_clksize;
     43 };
     44 
     45 struct imxccm_init_parent;
     46 
     47 void imx6ccm_attach_common(device_t, struct imx6_clk *, int,
     48     struct imxccm_init_parent *);
     49 
     50 struct clk *imx6_get_clock(struct imx6ccm_softc *, const char *);
     51 struct imx6_clk *imx6_clk_find(struct imx6ccm_softc *sc, const char *);
     52 
     53 struct imxccm_init_parent {
     54 	const char *clock;
     55 	const char *parent;
     56 };
     57 
     58 
     59 enum imx6_clk_type {
     60 	IMX6_CLK_FIXED,
     61 	IMX6_CLK_FIXED_FACTOR,
     62 	IMX6_CLK_PLL,
     63 	IMX6_CLK_MUX,
     64 	IMX6_CLK_GATE,
     65 	IMX6_CLK_PFD,
     66 	IMX6_CLK_DIV,
     67 };
     68 
     69 enum imx6_clk_reg {
     70 	IMX6_CLK_REG_CCM,
     71 	IMX6_CLK_REG_CCM_ANALOG,
     72 };
     73 
     74 enum imx6_clk_pll_type {
     75 	IMX6_CLK_PLL_GENERIC,
     76 	IMX6_CLK_PLL_SYS,
     77 	IMX6_CLK_PLL_USB,
     78 	IMX6_CLK_PLL_AUDIO_VIDEO,
     79 	IMX6_CLK_PLL_ENET,
     80 };
     81 
     82 enum imx6_clk_div_type {
     83 	IMX6_CLK_DIV_NORMAL,
     84 	IMX6_CLK_DIV_BUSY,
     85 	IMX6_CLK_DIV_TABLE,
     86 };
     87 
     88 enum imx6_clk_mux_type {
     89 	IMX6_CLK_MUX_NORMAL,
     90 	IMX6_CLK_MUX_BUSY,
     91 };
     92 
     93 struct imx6_clk_fixed {
     94 	u_int rate;
     95 };
     96 
     97 struct imx6_clk_fixed_factor {
     98 	u_int div;
     99 	u_int mult;
    100 };
    101 
    102 struct imx6_clk_pfd {
    103 	uint32_t reg;
    104 	int index;
    105 };
    106 
    107 struct imx6_clk_pll {
    108 	enum imx6_clk_pll_type type;
    109 	uint32_t reg;
    110 	uint32_t mask;
    111 	uint32_t powerdown;
    112 	unsigned long ref;
    113 };
    114 
    115 struct imx6_clk_div {
    116 	enum imx6_clk_div_type type;
    117 	enum imx6_clk_reg base;
    118 	uint32_t reg;
    119 	uint32_t mask;
    120 	uint32_t busy_reg;
    121 	uint32_t busy_mask;
    122 	const int *tbl;
    123 };
    124 
    125 struct imx6_clk_mux {
    126 	enum imx6_clk_mux_type type;
    127 	enum imx6_clk_reg base;
    128 	uint32_t reg;
    129 	uint32_t mask;
    130 	const char **parents;
    131 	u_int nparents;
    132 	uint32_t busy_reg;
    133 	uint32_t busy_mask;
    134 };
    135 
    136 struct imx6_clk_gate {
    137 	enum imx6_clk_reg base;
    138 	uint32_t reg;
    139 	uint32_t mask;
    140 	uint32_t exclusive_mask;
    141 };
    142 
    143 struct imx6_clk {
    144 	struct clk base;		/* must be first */
    145 
    146 	const char *parent;
    147 	u_int refcnt;
    148 
    149 	enum imx6_clk_type type;
    150 	union {
    151 		struct imx6_clk_fixed fixed;
    152 		struct imx6_clk_fixed_factor fixed_factor;
    153 		struct imx6_clk_pfd pfd;
    154 		struct imx6_clk_pll pll;
    155 		struct imx6_clk_div div;
    156 		struct imx6_clk_mux mux;
    157 		struct imx6_clk_gate gate;
    158 	} clk;
    159 };
    160 
    161 #define CLK_FIXED(_name, _rate) {				\
    162 	.base = { .name = (_name) },				\
    163 	.type = IMX6_CLK_FIXED,					\
    164 	.clk = {						\
    165 		.fixed = {					\
    166 			.rate = (_rate),			\
    167 		}						\
    168 	}							\
    169 }
    170 
    171 #define CLK_FIXED_FACTOR(_name, _parent, _div, _mult) {		\
    172 	.base = { .name = (_name) },				\
    173 	.type = IMX6_CLK_FIXED_FACTOR,				\
    174 	.parent = (_parent),					\
    175 	.clk = {						\
    176 		.fixed_factor = {				\
    177 			.div = (_div),				\
    178 			.mult = (_mult),			\
    179 		}						\
    180 	}							\
    181 }
    182 
    183 #define CLK_PFD(_name, _parent, _reg, _index) {			\
    184 	.base = { .name = (_name) },				\
    185 	.type = IMX6_CLK_PFD,					\
    186 	.parent = (_parent),					\
    187 	.clk = {						\
    188 		.pfd = {					\
    189 			.reg = (CCM_ANALOG_##_reg),		\
    190 			.index = (_index),			\
    191 		}						\
    192 	}							\
    193 }
    194 
    195 #define CLK_PLL(_name, _parent, _type, _reg, _mask, _powerdown, _ref) { \
    196 	.base = { .name = (_name) },				\
    197 	.type = IMX6_CLK_PLL,					\
    198 	.parent = (_parent),					\
    199 	.clk = {						\
    200 		.pll = {					\
    201 			.type = (IMX6_CLK_PLL_##_type),		\
    202 			.reg = (CCM_ANALOG_##_reg),		\
    203 			.mask = (CCM_ANALOG_##_reg##_##_mask),	\
    204 			.powerdown = (CCM_ANALOG_##_reg##_##_powerdown), \
    205 			.ref = (_ref),				\
    206 		}						\
    207 	}							\
    208 }
    209 
    210 #define CLK_DIV(_name, _parent, _reg, _mask) {			\
    211 	.base = { .name = (_name) },				\
    212 	.type = IMX6_CLK_DIV,					\
    213 	.parent = (_parent),					\
    214 	.clk = {						\
    215 		.div = {					\
    216 			.type = (IMX6_CLK_DIV_NORMAL),		\
    217 			.base = (IMX6_CLK_REG_CCM),		\
    218 			.reg = (CCM_##_reg),			\
    219 			.mask = (CCM_##_reg##_##_mask),		\
    220 		}						\
    221 	}							\
    222 }
    223 
    224 #define CLK_DIV_BUSY(_name, _parent, _reg, _mask, _busy_reg, _busy_mask) { \
    225 	.base = { .name = (_name) },				\
    226 	.type = IMX6_CLK_DIV,					\
    227 	.parent = (_parent),					\
    228 	.clk = {						\
    229 		.div = {					\
    230 			.type = (IMX6_CLK_DIV_BUSY),		\
    231 			.base = (IMX6_CLK_REG_CCM),		\
    232 			.reg = (CCM_##_reg),			\
    233 			.mask = (CCM_##_reg##_##_mask),	\
    234 			.busy_reg = (CCM_##_busy_reg),		\
    235 			.busy_mask = (CCM_##_busy_reg##_##_busy_mask) \
    236 		}						\
    237 	}							\
    238 }
    239 
    240 #define CLK_DIV_TABLE(_name, _parent, _reg, _mask, _tbl) {	\
    241 	.base = { .name = (_name) },				\
    242 	.type = IMX6_CLK_DIV,					\
    243 	.parent = (_parent),					\
    244 	.clk = {						\
    245 		.div = {					\
    246 			.type = (IMX6_CLK_DIV_TABLE),		\
    247 			.base = (IMX6_CLK_REG_CCM_ANALOG),	\
    248 			.reg = (CCM_ANALOG_##_reg),		\
    249 			.mask = (CCM_ANALOG_##_reg##_##_mask),	\
    250 			.tbl = (_tbl)				\
    251 		}						\
    252 	}							\
    253 }
    254 
    255 #define CLK_MUX(_name, _parents, _base, _reg, _mask) {		\
    256 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
    257 	.type = IMX6_CLK_MUX,					\
    258 	.clk = {						\
    259 		.mux = {					\
    260 			.type = (IMX6_CLK_MUX_NORMAL),		\
    261 			.base = (IMX6_CLK_REG_##_base),		\
    262 			.reg = (_base##_##_reg),		\
    263 			.mask = (_base##_##_reg##_##_mask),	\
    264 			.parents = (_parents),			\
    265 			.nparents = __arraycount(_parents)	\
    266 		}						\
    267 	}							\
    268 }
    269 
    270 #define CLK_MUX_BUSY(_name, _parents, _reg, _mask, _busy_reg, _busy_mask) { \
    271 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
    272 	.type = IMX6_CLK_MUX,					\
    273 	.clk = {						\
    274 		.mux = {					\
    275 			.type = (IMX6_CLK_MUX_BUSY),		\
    276 			.base = (IMX6_CLK_REG_CCM),		\
    277 			.reg = (CCM_##_reg),			\
    278 			.mask = (CCM_##_reg##_##_mask),		\
    279 			.parents = (_parents),			\
    280 			.nparents = __arraycount(_parents),	\
    281 			.busy_reg = (CCM_##_busy_reg),		\
    282 			.busy_mask = (CCM_##_busy_reg##_##_busy_mask) \
    283 		}						\
    284 	}							\
    285 }
    286 
    287 #define CLK_GATE(_name, _parent, _base, _reg, _mask) {		\
    288 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
    289 	.type = IMX6_CLK_GATE,					\
    290 	.parent = (_parent),					\
    291 	.clk = {						\
    292 		.gate = {					\
    293 			.base = (IMX6_CLK_REG_##_base),		\
    294 			.reg = (_base##_##_reg),		\
    295 			.mask = (_base##_##_reg##_##_mask),	\
    296 			.exclusive_mask = 0			\
    297 		}						\
    298 	}							\
    299 }
    300 
    301 #define CLK_GATE_EXCLUSIVE(_name, _parent, _base, _reg, _mask, _exclusive_mask) {  \
    302 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
    303 	.type = IMX6_CLK_GATE,					\
    304 	.parent = (_parent),					\
    305 	.clk = {						\
    306 		.gate = {					\
    307 			.base = (IMX6_CLK_REG_##_base),		\
    308 			.reg = (_base##_##_reg),		\
    309 			.mask = (_base##_##_reg##_##_mask),     \
    310 			.exclusive_mask = (_base##_##_reg##_##_exclusive_mask) \
    311 		}						\
    312 	}							\
    313 }
    314 
    315 #endif	/* _ARM_NXP_IMX6_CCMVAR_H_ */
    316