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