xref: /netbsd-src/sys/arch/arm/nxp/imx6_ccmvar.h (revision 5fd4005d8b7a68771ba913bcb5e99de942b2e13b)
1*5fd4005dSbouyer /*	$NetBSD: imx6_ccmvar.h,v 1.3 2023/05/04 13:25:07 bouyer Exp $	*/
28644267aSskrll /*
38644267aSskrll  * Copyright (c) 2012,2019  Genetec Corporation.  All rights reserved.
48644267aSskrll  * Written by Hashimoto Kenichi for Genetec Corporation.
58644267aSskrll  *
68644267aSskrll  * Redistribution and use in source and binary forms, with or without
78644267aSskrll  * modification, are permitted provided that the following conditions
88644267aSskrll  * are met:
98644267aSskrll  * 1. Redistributions of source code must retain the above copyright
108644267aSskrll  *    notice, this list of conditions and the following disclaimer.
118644267aSskrll  * 2. Redistributions in binary form must reproduce the above copyright
128644267aSskrll  *    notice, this list of conditions and the following disclaimer in the
138644267aSskrll  *    documentation and/or other materials provided with the distribution.
148644267aSskrll  *
158644267aSskrll  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
168644267aSskrll  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
178644267aSskrll  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
188644267aSskrll  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
198644267aSskrll  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
208644267aSskrll  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
218644267aSskrll  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
228644267aSskrll  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
238644267aSskrll  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
248644267aSskrll  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
258644267aSskrll  * POSSIBILITY OF SUCH DAMAGE.
268644267aSskrll  */
278644267aSskrll 
288644267aSskrll #ifndef	_ARM_NXP_IMX6_CCMVAR_H_
298644267aSskrll #define	_ARM_NXP_IMX6_CCMVAR_H_
308644267aSskrll 
318644267aSskrll #include <dev/clk/clk.h>
328644267aSskrll #include <dev/clk/clk_backend.h>
338644267aSskrll 
348644267aSskrll struct imx6ccm_softc {
358644267aSskrll 	device_t sc_dev;
368644267aSskrll 	bus_space_tag_t sc_iot;
378644267aSskrll 	bus_space_handle_t sc_ioh;
388644267aSskrll 	bus_space_handle_t sc_ioh_analog;
398644267aSskrll 
408644267aSskrll 	struct clk_domain sc_clkdom;
413e5af17bSbouyer 	struct imx6_clk *sc_imx6_clks;
423e5af17bSbouyer 	int sc_imx6_clksize;
438644267aSskrll };
448644267aSskrll 
45*5fd4005dSbouyer struct imxccm_init_parent;
46*5fd4005dSbouyer 
47*5fd4005dSbouyer void imx6ccm_attach_common(device_t, struct imx6_clk *, int,
48*5fd4005dSbouyer     struct imxccm_init_parent *);
498644267aSskrll 
503e5af17bSbouyer struct clk *imx6_get_clock(struct imx6ccm_softc *, const char *);
513e5af17bSbouyer struct imx6_clk *imx6_clk_find(struct imx6ccm_softc *sc, const char *);
528644267aSskrll 
53*5fd4005dSbouyer struct imxccm_init_parent {
54*5fd4005dSbouyer 	const char *clock;
55*5fd4005dSbouyer 	const char *parent;
56*5fd4005dSbouyer };
57*5fd4005dSbouyer 
588644267aSskrll 
598644267aSskrll enum imx6_clk_type {
608644267aSskrll 	IMX6_CLK_FIXED,
618644267aSskrll 	IMX6_CLK_FIXED_FACTOR,
628644267aSskrll 	IMX6_CLK_PLL,
638644267aSskrll 	IMX6_CLK_MUX,
648644267aSskrll 	IMX6_CLK_GATE,
658644267aSskrll 	IMX6_CLK_PFD,
668644267aSskrll 	IMX6_CLK_DIV,
678644267aSskrll };
688644267aSskrll 
698644267aSskrll enum imx6_clk_reg {
708644267aSskrll 	IMX6_CLK_REG_CCM,
718644267aSskrll 	IMX6_CLK_REG_CCM_ANALOG,
728644267aSskrll };
738644267aSskrll 
748644267aSskrll enum imx6_clk_pll_type {
758644267aSskrll 	IMX6_CLK_PLL_GENERIC,
768644267aSskrll 	IMX6_CLK_PLL_SYS,
778644267aSskrll 	IMX6_CLK_PLL_USB,
788644267aSskrll 	IMX6_CLK_PLL_AUDIO_VIDEO,
798644267aSskrll 	IMX6_CLK_PLL_ENET,
808644267aSskrll };
818644267aSskrll 
828644267aSskrll enum imx6_clk_div_type {
838644267aSskrll 	IMX6_CLK_DIV_NORMAL,
848644267aSskrll 	IMX6_CLK_DIV_BUSY,
858644267aSskrll 	IMX6_CLK_DIV_TABLE,
868644267aSskrll };
878644267aSskrll 
888644267aSskrll enum imx6_clk_mux_type {
898644267aSskrll 	IMX6_CLK_MUX_NORMAL,
908644267aSskrll 	IMX6_CLK_MUX_BUSY,
918644267aSskrll };
928644267aSskrll 
938644267aSskrll struct imx6_clk_fixed {
948644267aSskrll 	u_int rate;
958644267aSskrll };
968644267aSskrll 
978644267aSskrll struct imx6_clk_fixed_factor {
988644267aSskrll 	u_int div;
998644267aSskrll 	u_int mult;
1008644267aSskrll };
1018644267aSskrll 
1028644267aSskrll struct imx6_clk_pfd {
1038644267aSskrll 	uint32_t reg;
1048644267aSskrll 	int index;
1058644267aSskrll };
1068644267aSskrll 
1078644267aSskrll struct imx6_clk_pll {
1088644267aSskrll 	enum imx6_clk_pll_type type;
1098644267aSskrll 	uint32_t reg;
1108644267aSskrll 	uint32_t mask;
1118644267aSskrll 	uint32_t powerdown;
1128644267aSskrll 	unsigned long ref;
1138644267aSskrll };
1148644267aSskrll 
1158644267aSskrll struct imx6_clk_div {
1168644267aSskrll 	enum imx6_clk_div_type type;
1178644267aSskrll 	enum imx6_clk_reg base;
1188644267aSskrll 	uint32_t reg;
1198644267aSskrll 	uint32_t mask;
1208644267aSskrll 	uint32_t busy_reg;
1218644267aSskrll 	uint32_t busy_mask;
1228644267aSskrll 	const int *tbl;
1238644267aSskrll };
1248644267aSskrll 
1258644267aSskrll struct imx6_clk_mux {
1268644267aSskrll 	enum imx6_clk_mux_type type;
1278644267aSskrll 	enum imx6_clk_reg base;
1288644267aSskrll 	uint32_t reg;
1298644267aSskrll 	uint32_t mask;
1308644267aSskrll 	const char **parents;
1318644267aSskrll 	u_int nparents;
1328644267aSskrll 	uint32_t busy_reg;
1338644267aSskrll 	uint32_t busy_mask;
1348644267aSskrll };
1358644267aSskrll 
1368644267aSskrll struct imx6_clk_gate {
1378644267aSskrll 	enum imx6_clk_reg base;
1388644267aSskrll 	uint32_t reg;
1398644267aSskrll 	uint32_t mask;
1408644267aSskrll 	uint32_t exclusive_mask;
1418644267aSskrll };
1428644267aSskrll 
1438644267aSskrll struct imx6_clk {
1448644267aSskrll 	struct clk base;		/* must be first */
1458644267aSskrll 
1468644267aSskrll 	const char *parent;
1478644267aSskrll 	u_int refcnt;
1488644267aSskrll 
1498644267aSskrll 	enum imx6_clk_type type;
1508644267aSskrll 	union {
1518644267aSskrll 		struct imx6_clk_fixed fixed;
1528644267aSskrll 		struct imx6_clk_fixed_factor fixed_factor;
1538644267aSskrll 		struct imx6_clk_pfd pfd;
1548644267aSskrll 		struct imx6_clk_pll pll;
1558644267aSskrll 		struct imx6_clk_div div;
1568644267aSskrll 		struct imx6_clk_mux mux;
1578644267aSskrll 		struct imx6_clk_gate gate;
1588644267aSskrll 	} clk;
1598644267aSskrll };
1608644267aSskrll 
1618644267aSskrll #define CLK_FIXED(_name, _rate) {				\
1628644267aSskrll 	.base = { .name = (_name) },				\
1638644267aSskrll 	.type = IMX6_CLK_FIXED,					\
1648644267aSskrll 	.clk = {						\
1658644267aSskrll 		.fixed = {					\
1668644267aSskrll 			.rate = (_rate),			\
1678644267aSskrll 		}						\
1688644267aSskrll 	}							\
1698644267aSskrll }
1708644267aSskrll 
1718644267aSskrll #define CLK_FIXED_FACTOR(_name, _parent, _div, _mult) {		\
1728644267aSskrll 	.base = { .name = (_name) },				\
1738644267aSskrll 	.type = IMX6_CLK_FIXED_FACTOR,				\
1748644267aSskrll 	.parent = (_parent),					\
1758644267aSskrll 	.clk = {						\
1768644267aSskrll 		.fixed_factor = {				\
1778644267aSskrll 			.div = (_div),				\
1788644267aSskrll 			.mult = (_mult),			\
1798644267aSskrll 		}						\
1808644267aSskrll 	}							\
1818644267aSskrll }
1828644267aSskrll 
1838644267aSskrll #define CLK_PFD(_name, _parent, _reg, _index) {			\
1848644267aSskrll 	.base = { .name = (_name) },				\
1858644267aSskrll 	.type = IMX6_CLK_PFD,					\
1868644267aSskrll 	.parent = (_parent),					\
1878644267aSskrll 	.clk = {						\
1888644267aSskrll 		.pfd = {					\
1898644267aSskrll 			.reg = (CCM_ANALOG_##_reg),		\
1908644267aSskrll 			.index = (_index),			\
1918644267aSskrll 		}						\
1928644267aSskrll 	}							\
1938644267aSskrll }
1948644267aSskrll 
1958644267aSskrll #define CLK_PLL(_name, _parent, _type, _reg, _mask, _powerdown, _ref) { \
1968644267aSskrll 	.base = { .name = (_name) },				\
1978644267aSskrll 	.type = IMX6_CLK_PLL,					\
1988644267aSskrll 	.parent = (_parent),					\
1998644267aSskrll 	.clk = {						\
2008644267aSskrll 		.pll = {					\
2018644267aSskrll 			.type = (IMX6_CLK_PLL_##_type),		\
2028644267aSskrll 			.reg = (CCM_ANALOG_##_reg),		\
2038644267aSskrll 			.mask = (CCM_ANALOG_##_reg##_##_mask),	\
2048644267aSskrll 			.powerdown = (CCM_ANALOG_##_reg##_##_powerdown), \
2058644267aSskrll 			.ref = (_ref),				\
2068644267aSskrll 		}						\
2078644267aSskrll 	}							\
2088644267aSskrll }
2098644267aSskrll 
2108644267aSskrll #define CLK_DIV(_name, _parent, _reg, _mask) {			\
2118644267aSskrll 	.base = { .name = (_name) },				\
2128644267aSskrll 	.type = IMX6_CLK_DIV,					\
2138644267aSskrll 	.parent = (_parent),					\
2148644267aSskrll 	.clk = {						\
2158644267aSskrll 		.div = {					\
2168644267aSskrll 			.type = (IMX6_CLK_DIV_NORMAL),		\
2178644267aSskrll 			.base = (IMX6_CLK_REG_CCM),		\
2188644267aSskrll 			.reg = (CCM_##_reg),			\
2198644267aSskrll 			.mask = (CCM_##_reg##_##_mask),		\
2208644267aSskrll 		}						\
2218644267aSskrll 	}							\
2228644267aSskrll }
2238644267aSskrll 
2248644267aSskrll #define CLK_DIV_BUSY(_name, _parent, _reg, _mask, _busy_reg, _busy_mask) { \
2258644267aSskrll 	.base = { .name = (_name) },				\
2268644267aSskrll 	.type = IMX6_CLK_DIV,					\
2278644267aSskrll 	.parent = (_parent),					\
2288644267aSskrll 	.clk = {						\
2298644267aSskrll 		.div = {					\
2308644267aSskrll 			.type = (IMX6_CLK_DIV_BUSY),		\
2318644267aSskrll 			.base = (IMX6_CLK_REG_CCM),		\
2328644267aSskrll 			.reg = (CCM_##_reg),			\
2338644267aSskrll 			.mask = (CCM_##_reg##_##_mask),	\
2348644267aSskrll 			.busy_reg = (CCM_##_busy_reg),		\
2358644267aSskrll 			.busy_mask = (CCM_##_busy_reg##_##_busy_mask) \
2368644267aSskrll 		}						\
2378644267aSskrll 	}							\
2388644267aSskrll }
2398644267aSskrll 
2408644267aSskrll #define CLK_DIV_TABLE(_name, _parent, _reg, _mask, _tbl) {	\
2418644267aSskrll 	.base = { .name = (_name) },				\
2428644267aSskrll 	.type = IMX6_CLK_DIV,					\
2438644267aSskrll 	.parent = (_parent),					\
2448644267aSskrll 	.clk = {						\
2458644267aSskrll 		.div = {					\
2468644267aSskrll 			.type = (IMX6_CLK_DIV_TABLE),		\
2478644267aSskrll 			.base = (IMX6_CLK_REG_CCM_ANALOG),	\
2488644267aSskrll 			.reg = (CCM_ANALOG_##_reg),		\
2498644267aSskrll 			.mask = (CCM_ANALOG_##_reg##_##_mask),	\
2508644267aSskrll 			.tbl = (_tbl)				\
2518644267aSskrll 		}						\
2528644267aSskrll 	}							\
2538644267aSskrll }
2548644267aSskrll 
2558644267aSskrll #define CLK_MUX(_name, _parents, _base, _reg, _mask) {		\
2568644267aSskrll 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
2578644267aSskrll 	.type = IMX6_CLK_MUX,					\
2588644267aSskrll 	.clk = {						\
2598644267aSskrll 		.mux = {					\
2608644267aSskrll 			.type = (IMX6_CLK_MUX_NORMAL),		\
2618644267aSskrll 			.base = (IMX6_CLK_REG_##_base),		\
2628644267aSskrll 			.reg = (_base##_##_reg),		\
2638644267aSskrll 			.mask = (_base##_##_reg##_##_mask),	\
2648644267aSskrll 			.parents = (_parents),			\
2658644267aSskrll 			.nparents = __arraycount(_parents)	\
2668644267aSskrll 		}						\
2678644267aSskrll 	}							\
2688644267aSskrll }
2698644267aSskrll 
2708644267aSskrll #define CLK_MUX_BUSY(_name, _parents, _reg, _mask, _busy_reg, _busy_mask) { \
2718644267aSskrll 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
2728644267aSskrll 	.type = IMX6_CLK_MUX,					\
2738644267aSskrll 	.clk = {						\
2748644267aSskrll 		.mux = {					\
2758644267aSskrll 			.type = (IMX6_CLK_MUX_BUSY),		\
2768644267aSskrll 			.base = (IMX6_CLK_REG_CCM),		\
2778644267aSskrll 			.reg = (CCM_##_reg),			\
2788644267aSskrll 			.mask = (CCM_##_reg##_##_mask),		\
2798644267aSskrll 			.parents = (_parents),			\
2808644267aSskrll 			.nparents = __arraycount(_parents),	\
2818644267aSskrll 			.busy_reg = (CCM_##_busy_reg),		\
2828644267aSskrll 			.busy_mask = (CCM_##_busy_reg##_##_busy_mask) \
2838644267aSskrll 		}						\
2848644267aSskrll 	}							\
2858644267aSskrll }
2868644267aSskrll 
2878644267aSskrll #define CLK_GATE(_name, _parent, _base, _reg, _mask) {		\
2888644267aSskrll 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
2898644267aSskrll 	.type = IMX6_CLK_GATE,					\
2908644267aSskrll 	.parent = (_parent),					\
2918644267aSskrll 	.clk = {						\
2928644267aSskrll 		.gate = {					\
2938644267aSskrll 			.base = (IMX6_CLK_REG_##_base),		\
2948644267aSskrll 			.reg = (_base##_##_reg),		\
2958644267aSskrll 			.mask = (_base##_##_reg##_##_mask),	\
2968644267aSskrll 			.exclusive_mask = 0			\
2978644267aSskrll 		}						\
2988644267aSskrll 	}							\
2998644267aSskrll }
3008644267aSskrll 
3018644267aSskrll #define CLK_GATE_EXCLUSIVE(_name, _parent, _base, _reg, _mask, _exclusive_mask) {  \
3028644267aSskrll 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
3038644267aSskrll 	.type = IMX6_CLK_GATE,					\
3048644267aSskrll 	.parent = (_parent),					\
3058644267aSskrll 	.clk = {						\
3068644267aSskrll 		.gate = {					\
3078644267aSskrll 			.base = (IMX6_CLK_REG_##_base),		\
3088644267aSskrll 			.reg = (_base##_##_reg),		\
3098644267aSskrll 			.mask = (_base##_##_reg##_##_mask),     \
3108644267aSskrll 			.exclusive_mask = (_base##_##_reg##_##_exclusive_mask) \
3118644267aSskrll 		}						\
3128644267aSskrll 	}							\
3138644267aSskrll }
3148644267aSskrll 
3158644267aSskrll #endif	/* _ARM_NXP_IMX6_CCMVAR_H_ */
316