xref: /netbsd-src/sys/arch/arm/imx/imx23_apbh.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /* $Id: imx23_apbh.c,v 1.3 2021/08/07 16:18:44 thorpej Exp $ */
2eba5cacbSjkunz 
3eba5cacbSjkunz /*
4eba5cacbSjkunz  * Copyright (c) 2012 The NetBSD Foundation, Inc.
5eba5cacbSjkunz  * All rights reserved.
6eba5cacbSjkunz  *
7eba5cacbSjkunz  * This code is derived from software contributed to The NetBSD Foundation
8eba5cacbSjkunz  * by Petri Laakso.
9eba5cacbSjkunz  *
10eba5cacbSjkunz  * Redistribution and use in source and binary forms, with or without
11eba5cacbSjkunz  * modification, are permitted provided that the following conditions
12eba5cacbSjkunz  * are met:
13eba5cacbSjkunz  * 1. Redistributions of source code must retain the above copyright
14eba5cacbSjkunz  *    notice, this list of conditions and the following disclaimer.
15eba5cacbSjkunz  * 2. Redistributions in binary form must reproduce the above copyright
16eba5cacbSjkunz  *    notice, this list of conditions and the following disclaimer in the
17eba5cacbSjkunz  *    documentation and/or other materials provided with the distribution.
18eba5cacbSjkunz  *
19eba5cacbSjkunz  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20eba5cacbSjkunz  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21eba5cacbSjkunz  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22eba5cacbSjkunz  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23eba5cacbSjkunz  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24eba5cacbSjkunz  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25eba5cacbSjkunz  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26eba5cacbSjkunz  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27eba5cacbSjkunz  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28eba5cacbSjkunz  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29eba5cacbSjkunz  * POSSIBILITY OF SUCH DAMAGE.
30eba5cacbSjkunz  */
31eba5cacbSjkunz 
32eba5cacbSjkunz #include <sys/param.h>
33eba5cacbSjkunz #include <sys/bus.h>
34eba5cacbSjkunz #include <sys/device.h>
35eba5cacbSjkunz #include <sys/errno.h>
36eba5cacbSjkunz 
37eba5cacbSjkunz #include <arm/mainbus/mainbus.h>
38eba5cacbSjkunz 
39eba5cacbSjkunz #include <arm/imx/imx23var.h>
40eba5cacbSjkunz 
41eba5cacbSjkunz #include "locators.h"
42eba5cacbSjkunz 
43eba5cacbSjkunz static int	apbh_match(device_t, cfdata_t, void *);
44eba5cacbSjkunz static void	apbh_attach(device_t, device_t, void *);
45eba5cacbSjkunz static int	apbh_detach(device_t, int);
46eba5cacbSjkunz static int	apbh_activate(device_t, enum devact);
47eba5cacbSjkunz 
48eba5cacbSjkunz static int	apbh_search_cb(device_t, cfdata_t, const int *, void *);
49eba5cacbSjkunz static int	apbh_search_crit_cb(device_t, cfdata_t, const int *, void *);
50eba5cacbSjkunz static int	apbh_print(void *,const char *);
51eba5cacbSjkunz 
52eba5cacbSjkunz struct apbh_softc {
53eba5cacbSjkunz 	device_t	sc_dev;
54eba5cacbSjkunz 	device_t	dmac; /* DMA controller device for this bus. */
55eba5cacbSjkunz };
56eba5cacbSjkunz 
57eba5cacbSjkunz CFATTACH_DECL3_NEW(apbh,
58eba5cacbSjkunz 	sizeof(struct apbh_softc),
59eba5cacbSjkunz 	apbh_match,
60eba5cacbSjkunz 	apbh_attach,
61eba5cacbSjkunz 	apbh_detach,
62eba5cacbSjkunz 	apbh_activate,
63eba5cacbSjkunz 	NULL,
64eba5cacbSjkunz 	NULL,
65eba5cacbSjkunz 	0);
66eba5cacbSjkunz 
67eba5cacbSjkunz static int
apbh_match(device_t parent,cfdata_t match,void * aux)68eba5cacbSjkunz apbh_match(device_t parent, cfdata_t match, void *aux)
69eba5cacbSjkunz {
70eba5cacbSjkunz 	struct mainbus_attach_args *mb = aux;
71eba5cacbSjkunz 
72eba5cacbSjkunz 	if ((mb->mb_iobase == APBH_BASE) && (mb->mb_iosize == APBH_SIZE))
73eba5cacbSjkunz 		return 1;
74eba5cacbSjkunz 
75eba5cacbSjkunz 	return 0;
76eba5cacbSjkunz }
77eba5cacbSjkunz 
78eba5cacbSjkunz static void
apbh_attach(device_t parent,device_t self,void * aux)79eba5cacbSjkunz apbh_attach(device_t parent, device_t self, void *aux)
80eba5cacbSjkunz {
81eba5cacbSjkunz 	struct apb_attach_args aa;
82eba5cacbSjkunz 	static int apbh_attached = 0;
83eba5cacbSjkunz 
84eba5cacbSjkunz 	if (apbh_attached)
85eba5cacbSjkunz 		return;
86eba5cacbSjkunz 
87eba5cacbSjkunz 	aa.aa_iot = &imx23_bus_space;
88eba5cacbSjkunz 	aa.aa_dmat = &imx23_bus_dma_tag;
89eba5cacbSjkunz 
90eba5cacbSjkunz 	aprint_normal("\n");
91eba5cacbSjkunz 
922685996bSthorpej 	config_search(self, &aa,
93*c7fb772bSthorpej 	    CFARGS(.search = apbh_search_crit_cb));
942685996bSthorpej 	config_search(self, &aa,
95*c7fb772bSthorpej 	    CFARGS(.search = apbh_search_cb));
96eba5cacbSjkunz 
97eba5cacbSjkunz 	apbh_attached = 1;
98eba5cacbSjkunz 
99eba5cacbSjkunz 	return;
100eba5cacbSjkunz }
101eba5cacbSjkunz 
102eba5cacbSjkunz static int
apbh_detach(device_t self,int flags)103eba5cacbSjkunz apbh_detach(device_t self, int flags)
104eba5cacbSjkunz {
105eba5cacbSjkunz 	return 0;
106eba5cacbSjkunz }
107eba5cacbSjkunz 
108eba5cacbSjkunz static int
apbh_activate(device_t self,enum devact act)109eba5cacbSjkunz apbh_activate(device_t self, enum devact act)
110eba5cacbSjkunz {
111eba5cacbSjkunz 	return EOPNOTSUPP;
112eba5cacbSjkunz }
113eba5cacbSjkunz 
114eba5cacbSjkunz /*
115eba5cacbSjkunz  * config_search_ia() callback function.
116eba5cacbSjkunz  */
117eba5cacbSjkunz static int
apbh_search_cb(device_t parent,cfdata_t cf,const int * locs,void * aux)118eba5cacbSjkunz apbh_search_cb(device_t parent, cfdata_t cf, const int *locs, void *aux)
119eba5cacbSjkunz {
120eba5cacbSjkunz 	struct apb_attach_args *aa = aux;
121eba5cacbSjkunz 
122eba5cacbSjkunz 	aa->aa_name = cf->cf_name;
123eba5cacbSjkunz 	aa->aa_addr = cf->cf_loc[APBHCF_ADDR];
124eba5cacbSjkunz 	aa->aa_size = cf->cf_loc[APBHCF_SIZE];
125eba5cacbSjkunz 	aa->aa_irq = cf->cf_loc[APBHCF_IRQ];
126eba5cacbSjkunz 
1272685996bSthorpej 	if (config_probe(parent, cf, aux))
128*c7fb772bSthorpej 		config_attach(parent, cf, aux, apbh_print, CFARGS_NONE);
129eba5cacbSjkunz 
130eba5cacbSjkunz 	return 0;
131eba5cacbSjkunz }
132eba5cacbSjkunz 
133eba5cacbSjkunz /*
134eba5cacbSjkunz  * config_search_ia() callback function which only applies to critical devices.
135eba5cacbSjkunz  */
136eba5cacbSjkunz static int
apbh_search_crit_cb(device_t parent,cfdata_t cf,const int * locs,void * aux)137eba5cacbSjkunz apbh_search_crit_cb(device_t parent, cfdata_t cf, const int *locs, void *aux)
138eba5cacbSjkunz {
139eba5cacbSjkunz 	struct apb_attach_args *aa = aux;
140eba5cacbSjkunz 
141eba5cacbSjkunz 	/* Return if not critical device. */
142eba5cacbSjkunz 	if ((strcmp(cf->cf_name, "icoll") != 0)
143eba5cacbSjkunz 	    && (strcmp(cf->cf_name, "apbdma") != 0))
144eba5cacbSjkunz 		return 0;
145eba5cacbSjkunz 
146eba5cacbSjkunz 	aa->aa_name = cf->cf_name;
147eba5cacbSjkunz 	aa->aa_addr = cf->cf_loc[APBHCF_ADDR];
148eba5cacbSjkunz 	aa->aa_size = cf->cf_loc[APBHCF_SIZE];
149eba5cacbSjkunz 	aa->aa_irq = cf->cf_loc[APBHCF_IRQ];
150eba5cacbSjkunz 
1512685996bSthorpej 	if (config_probe(parent, cf, aux))
152*c7fb772bSthorpej 		config_attach(parent, cf, aux, apbh_print, CFARGS_NONE);
153eba5cacbSjkunz 
154eba5cacbSjkunz 	return 0;
155eba5cacbSjkunz }
156eba5cacbSjkunz 
157eba5cacbSjkunz /*
158eba5cacbSjkunz  * Called from config_attach()
159eba5cacbSjkunz  */
160eba5cacbSjkunz static int
apbh_print(void * aux,const char * name __unused)161eba5cacbSjkunz apbh_print(void *aux, const char *name __unused)
162eba5cacbSjkunz {
163eba5cacbSjkunz 	struct apb_attach_args *aa = aux;
164eba5cacbSjkunz 
165eba5cacbSjkunz 	if (aa->aa_addr != APBHCF_ADDR_DEFAULT) {
166eba5cacbSjkunz 		aprint_normal(" addr 0x%lx", aa->aa_addr);
167eba5cacbSjkunz 		if (aa->aa_size > APBHCF_SIZE_DEFAULT)
168eba5cacbSjkunz 			aprint_normal("-0x%lx", aa->aa_addr + aa->aa_size-1);
169eba5cacbSjkunz 	}
170eba5cacbSjkunz 
171eba5cacbSjkunz 	if (aa->aa_irq != APBHCF_IRQ_DEFAULT)
172eba5cacbSjkunz 		aprint_normal(" irq %d", aa->aa_irq);
173eba5cacbSjkunz 
174eba5cacbSjkunz 	return UNCONF;
175eba5cacbSjkunz }
176