xref: /netbsd-src/sys/arch/arm/imx/imx51_iomux.c (revision cbab9cadce21ae72fac13910001079fff214cc29)
1*cbab9cadSchs /*	$NetBSD: imx51_iomux.c,v 1.4 2012/10/27 17:17:39 chs Exp $	*/
2c1719a03Sbsh 
3c1719a03Sbsh /*
4c1719a03Sbsh  * Copyright (c) 2009, 2010  Genetec Corporation.  All rights reserved.
5c1719a03Sbsh  * Written by Hashimoto Kenichi for Genetec Corporation.
6c1719a03Sbsh  *
7c1719a03Sbsh  * Redistribution and use in source and binary forms, with or without
8c1719a03Sbsh  * modification, are permitted provided that the following conditions
9c1719a03Sbsh  * are met:
10c1719a03Sbsh  * 1. Redistributions of source code must retain the above copyright
11c1719a03Sbsh  *    notice, this list of conditions and the following disclaimer.
12c1719a03Sbsh  * 2. Redistributions in binary form must reproduce the above copyright
13c1719a03Sbsh  *    notice, this list of conditions and the following disclaimer in the
14c1719a03Sbsh  *    documentation and/or other materials provided with the distribution.
15c1719a03Sbsh  *
16c1719a03Sbsh  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
17c1719a03Sbsh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18c1719a03Sbsh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19c1719a03Sbsh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
20c1719a03Sbsh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21c1719a03Sbsh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22c1719a03Sbsh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23c1719a03Sbsh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24c1719a03Sbsh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25c1719a03Sbsh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26c1719a03Sbsh  * POSSIBILITY OF SUCH DAMAGE.
27c1719a03Sbsh  */
28c1719a03Sbsh #include <sys/cdefs.h>
29*cbab9cadSchs __KERNEL_RCSID(0, "$NetBSD: imx51_iomux.c,v 1.4 2012/10/27 17:17:39 chs Exp $");
30c1719a03Sbsh 
31c1719a03Sbsh #define	_INTR_PRIVATE
32c1719a03Sbsh 
33c1719a03Sbsh #include "locators.h"
34c1719a03Sbsh 
35c1719a03Sbsh #include <sys/param.h>
36c1719a03Sbsh #include <sys/evcnt.h>
37c1719a03Sbsh #include <sys/atomic.h>
38c1719a03Sbsh #include <sys/device.h>
39c1719a03Sbsh 
40c1719a03Sbsh #include <uvm/uvm_extern.h>
41c1719a03Sbsh 
42c1719a03Sbsh #include <machine/intr.h>
43c1719a03Sbsh 
44c1719a03Sbsh #include <arm/cpu.h>
45c1719a03Sbsh #include <arm/armreg.h>
46c1719a03Sbsh #include <arm/cpufunc.h>
47c1719a03Sbsh 
48ed9977b1Sdyoung #include <sys/bus.h>
49c1719a03Sbsh 
50c1719a03Sbsh #include <arm/imx/imx51reg.h>
51c1719a03Sbsh #include <arm/imx/imx51var.h>
52c1719a03Sbsh 
53c1719a03Sbsh struct iomux_softc {
54c1719a03Sbsh 	bus_space_tag_t iomux_memt;
55c1719a03Sbsh 	bus_space_handle_t iomux_memh;
56c1719a03Sbsh };
57c1719a03Sbsh 
58c1719a03Sbsh #define	IOMUX_READ(iomux, reg) \
59c1719a03Sbsh 	bus_space_read_4((iomux)->iomux_memt, (iomux)->iomux_memh, (reg))
60c1719a03Sbsh #define	IOMUX_WRITE(iomux, reg, val) \
61c1719a03Sbsh 	bus_space_write_4((iomux)->iomux_memt, (iomux)->iomux_memh, (reg), (val))
62c1719a03Sbsh 
63c1719a03Sbsh static int iomux_match(device_t, cfdata_t, void *);
64c1719a03Sbsh static void iomux_attach(device_t, device_t, void *);
65c1719a03Sbsh 
66c1719a03Sbsh static struct iomux_softc *iomuxsc = NULL;
67c1719a03Sbsh 
682768fb99Sbsh CFATTACH_DECL_NEW(imxiomux, sizeof(struct iomux_softc),
692768fb99Sbsh     iomux_match, iomux_attach, NULL, NULL);
70c1719a03Sbsh 
71c1719a03Sbsh int
iomux_match(device_t parent,cfdata_t cfdata,void * aux)72c1719a03Sbsh iomux_match(device_t parent, cfdata_t cfdata, void *aux)
73c1719a03Sbsh {
74c1719a03Sbsh 	struct axi_attach_args *axia = aux;
75c1719a03Sbsh 
76c1719a03Sbsh 	if (axia->aa_addr != IOMUXC_BASE)
77c1719a03Sbsh 		return 0;
78c1719a03Sbsh 
79c1719a03Sbsh 	return 1;
80c1719a03Sbsh }
81c1719a03Sbsh 
82c1719a03Sbsh void
iomux_attach(device_t parent,device_t self,void * aux)83c1719a03Sbsh iomux_attach(device_t parent, device_t self, void *aux)
84c1719a03Sbsh {
85c1719a03Sbsh 	struct axi_attach_args * const axia = aux;
86c1719a03Sbsh 	struct iomux_softc * const iomux = device_private(self);
87c1719a03Sbsh 	int error;
88c1719a03Sbsh 
89c1719a03Sbsh 	if (axia->aa_size == AXICF_SIZE_DEFAULT)
90c1719a03Sbsh 		axia->aa_size = IOMUXC_SIZE;
91c1719a03Sbsh 
92c1719a03Sbsh 	iomux->iomux_memt = axia->aa_iot;
93c1719a03Sbsh 	error = bus_space_map(axia->aa_iot, axia->aa_addr, axia->aa_size,
94c1719a03Sbsh 			      0, &iomux->iomux_memh);
95c1719a03Sbsh 
96c1719a03Sbsh 	if (error) {
97c1719a03Sbsh 		aprint_error(": failed to map register %#lx@%#lx: %d\n",
98c1719a03Sbsh 		    axia->aa_size, axia->aa_addr, error);
99c1719a03Sbsh 		return;
100c1719a03Sbsh 	}
101c1719a03Sbsh 
102c1719a03Sbsh 	aprint_normal("\n");
103c1719a03Sbsh 
104c1719a03Sbsh 	iomuxsc = iomux;
105c1719a03Sbsh }
106c1719a03Sbsh 
107c1719a03Sbsh static void
iomux_set_function_sub(struct iomux_softc * sc,uint32_t pin,uint32_t fn)108c1719a03Sbsh iomux_set_function_sub(struct iomux_softc *sc, uint32_t pin, uint32_t fn)
109c1719a03Sbsh {
110c1719a03Sbsh 	bus_size_t mux_ctl_reg = IOMUX_PIN_TO_MUX_ADDRESS(pin);
111c1719a03Sbsh 
112c1719a03Sbsh 	if (mux_ctl_reg != IOMUX_MUX_NONE)
113c1719a03Sbsh 		bus_space_write_4(sc->iomux_memt, sc->iomux_memh,
114c1719a03Sbsh 		    mux_ctl_reg, fn);
115c1719a03Sbsh }
116c1719a03Sbsh 
117c1719a03Sbsh void
iomux_set_function(unsigned int pin,unsigned int fn)118c1719a03Sbsh iomux_set_function(unsigned int pin, unsigned int fn)
119c1719a03Sbsh {
120c1719a03Sbsh 	iomux_set_function_sub(iomuxsc, pin, fn);
121c1719a03Sbsh }
122c1719a03Sbsh 
123c1719a03Sbsh 
124c1719a03Sbsh static void
iomux_set_pad_sub(struct iomux_softc * sc,uint32_t pin,uint32_t config)125c1719a03Sbsh iomux_set_pad_sub(struct iomux_softc *sc, uint32_t pin, uint32_t config)
126c1719a03Sbsh {
127c1719a03Sbsh 	bus_size_t pad_ctl_reg = IOMUX_PIN_TO_PAD_ADDRESS(pin);
128c1719a03Sbsh 
129c1719a03Sbsh 	if (pad_ctl_reg != IOMUX_PAD_NONE)
130c1719a03Sbsh 		bus_space_write_4(sc->iomux_memt, sc->iomux_memh,
131c1719a03Sbsh 		    pad_ctl_reg, config);
132c1719a03Sbsh }
133c1719a03Sbsh 
134c1719a03Sbsh void
iomux_set_pad(unsigned int pin,unsigned int config)135c1719a03Sbsh iomux_set_pad(unsigned int pin, unsigned int config)
136c1719a03Sbsh {
137c1719a03Sbsh 	iomux_set_pad_sub(iomuxsc, pin, config);
138c1719a03Sbsh }
139c1719a03Sbsh 
140c1719a03Sbsh #if 0
141c1719a03Sbsh void
142c1719a03Sbsh iomux_set_input(unsigned int input, unsigned int config)
143c1719a03Sbsh {
144c1719a03Sbsh 	bus_size_t input_ctl_reg = input;
145c1719a03Sbsh 
146c1719a03Sbsh 	bus_space_write_4(iomuxsc->iomux_memt, iomuxsc->iomux_memh,
147c1719a03Sbsh 	    input_ctl_reg, config);
148c1719a03Sbsh }
149c1719a03Sbsh #endif
150c1719a03Sbsh 
151c1719a03Sbsh void
iomux_mux_config(const struct iomux_conf * conflist)152c1719a03Sbsh iomux_mux_config(const struct iomux_conf *conflist)
153c1719a03Sbsh {
154c1719a03Sbsh 	int i;
155c1719a03Sbsh 
156c1719a03Sbsh 	for (i = 0; conflist[i].pin != IOMUX_CONF_EOT; i++) {
157c1719a03Sbsh 		iomux_set_pad_sub(iomuxsc, conflist[i].pin, conflist[i].pad);
158c1719a03Sbsh 		iomux_set_function_sub(iomuxsc, conflist[i].pin,
159c1719a03Sbsh 		    conflist[i].mux);
160c1719a03Sbsh 	}
161c1719a03Sbsh }
162c1719a03Sbsh 
163c1719a03Sbsh #if 0
164c1719a03Sbsh void
165c1719a03Sbsh iomux_input_config(const struct iomux_input_conf *conflist)
166c1719a03Sbsh {
167c1719a03Sbsh 	int i;
168c1719a03Sbsh 
169c1719a03Sbsh 	for (i = 0; conflist[i].inout != -1; i++) {
170c1719a03Sbsh 		iomux_set_inout(iomuxsc, conflist[i].inout,
171c1719a03Sbsh 		    conflist[i].inout_mode);
172c1719a03Sbsh 	}
173c1719a03Sbsh }
174c1719a03Sbsh #endif
175c1719a03Sbsh 
176