1/*	$NetBSD: tcic2var.h,v 1.15 2020/03/05 15:18:55 riastradh Exp $	*/
2
3/*
4 * Copyright (c) 1998, 1999 Christoph Badura.  All rights reserved.
5 * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by Marc Horowitz.
18 * 4. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _TCIC2VAR_H
34#define _TCIC2VAR_H
35
36#include <sys/device.h>
37
38#include <dev/pcmcia/pcmciareg.h>
39#include <dev/pcmcia/pcmciachip.h>
40
41#include <dev/ic/tcic2reg.h>
42
43struct proc;
44
45struct tcic_event {
46	SIMPLEQ_ENTRY(tcic_event) pe_q;
47	int pe_type;
48};
49
50/* pe_type */
51#define	TCIC_EVENT_INSERTION	0
52#define	TCIC_EVENT_REMOVAL	1
53
54
55struct tcic_handle {
56	struct tcic_softc *sc;
57	int	sock;				/* socket number */
58	int	flags;
59	int	sstat;				/* last value of R_SSTAT */
60	int	memalloc;
61	int	memwins;
62	struct {
63		bus_addr_t	addr;
64		bus_size_t	size;
65		int		size2;		/* size as 2^n scaled by 4K */
66		long		offset;
67		int		speed;		/* in ns */
68		int		kind;
69	} mem[TCIC_MAX_MEM_WINS];
70	int	ioalloc;
71	struct {
72		bus_addr_t	addr;
73		bus_size_t	size;
74		int		width;
75		int		speed;		/* in ns */
76	} io[TCIC_IO_WINS];
77	int	ih_irq;
78	device_t pcmcia;
79
80	int shutdown;
81	struct lwp *event_thread;
82	SIMPLEQ_HEAD(, tcic_event) events;
83};
84
85#define	TCIC_FLAG_SOCKETP	0x0001
86#define	TCIC_FLAG_CARDP		0x0002
87
88/*
89 * This is sort of arbitrary.  It merely needs to be "enough". It can be
90 * overridden in the conf file, anyway.
91 */
92
93#define	TCIC_MEM_PAGES	4
94#define	TCIC_MEMSIZE	TCIC_MEM_PAGES*TCIC_MEM_PAGESIZE
95
96#define	TCIC_NSLOTS	2
97
98struct tcic_softc {
99	device_t sc_dev;
100	bus_space_tag_t memt;
101	bus_space_handle_t memh;
102	bus_space_tag_t iot;
103	bus_space_handle_t ioh;
104
105	int	chipid;
106	int	validirqs;
107	int	pwrena;		/* holds TCIC_PWR_ENA on'084 and successors */
108
109	/* XXX isa_chipset_tag_t, pci_chipset_tag_t, etc. */
110	void	*intr_est;
111
112	pcmcia_chipset_tag_t pct;
113
114	/* this needs to be large enough to hold TCIC_MEM_PAGES bits */
115	int	subregionmask;
116
117	/* used by memory window mapping functions */
118	bus_addr_t membase;
119	int	memsize2;		/* int(log2(memsize)) */
120
121	/*
122	 * used by io window mapping functions.  These can actually overlap
123	 * with another tcic, since the underlying extent mapper will deal
124	 * with individual allocations.  This is here to deal with the fact
125	 * that different busses have different real widths (different pc
126	 * hardware seems to use 10 or 12 bits for the I/O bus).
127	 */
128	bus_addr_t iobase;
129	bus_size_t iosize;
130
131	int	irq;
132	void	*ih;
133
134	struct tcic_handle handle[TCIC_NSLOTS];
135};
136
137int	tcic_log2(u_int);
138int	tcic_ns2wscnt(int);
139
140int	tcic_check_reserved_bits(bus_space_tag_t, bus_space_handle_t);
141int	tcic_chipid(bus_space_tag_t, bus_space_handle_t);
142int	tcic_chipid_known(int);
143const char *tcic_chipid_to_string(int);
144int	tcic_validirqs(int);
145
146void	tcic_attach(struct tcic_softc *);
147void	tcic_attach_sockets(struct tcic_softc *);
148int	tcic_intr(void *arg);
149
150static __inline int tcic_read_1(struct tcic_handle *, int);
151static __inline int tcic_read_2(struct tcic_handle *, int);
152static __inline int tcic_read_4(struct tcic_handle *, int);
153static __inline void tcic_write_1(struct tcic_handle *, int, int);
154static __inline void tcic_write_2(struct tcic_handle *, int, int);
155static __inline void tcic_write_4(struct tcic_handle *, int, int);
156static __inline int tcic_read_ind_2(struct tcic_handle *, int);
157static __inline void tcic_write_ind_2(struct tcic_handle *, int, int);
158static __inline void tcic_sel_sock(struct tcic_handle *);
159static __inline void tcic_wait_ready(struct tcic_handle *);
160static __inline int tcic_read_aux_1(bus_space_tag_t, bus_space_handle_t, int, int);
161static __inline int tcic_read_aux_2(bus_space_tag_t, bus_space_handle_t, int);
162static __inline void tcic_write_aux_1(bus_space_tag_t, bus_space_handle_t, int, int, int);
163static __inline void tcic_write_aux_2(bus_space_tag_t, bus_space_handle_t, int, int);
164
165int	tcic_chip_mem_alloc(pcmcia_chipset_handle_t, bus_size_t,
166	    struct pcmcia_mem_handle *);
167void	tcic_chip_mem_free(pcmcia_chipset_handle_t,
168	    struct pcmcia_mem_handle *);
169int	tcic_chip_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t,
170	    bus_size_t, struct pcmcia_mem_handle *, bus_size_t *, int *);
171void	tcic_chip_mem_unmap(pcmcia_chipset_handle_t, int);
172
173int	tcic_chip_io_alloc(pcmcia_chipset_handle_t, bus_addr_t,
174	    bus_size_t, bus_size_t, struct pcmcia_io_handle *);
175void	tcic_chip_io_free(pcmcia_chipset_handle_t,
176	    struct pcmcia_io_handle *);
177int	tcic_chip_io_map(pcmcia_chipset_handle_t, int, bus_addr_t,
178	    bus_size_t, struct pcmcia_io_handle *, int *);
179void	tcic_chip_io_unmap(pcmcia_chipset_handle_t, int);
180
181void	tcic_chip_socket_enable(pcmcia_chipset_handle_t);
182void	tcic_chip_socket_disable(pcmcia_chipset_handle_t);
183void	tcic_chip_socket_settype(pcmcia_chipset_handle_t, int);
184
185static __inline int tcic_read_1(struct tcic_handle *, int);
186static __inline int
187tcic_read_1(struct tcic_handle *h, int reg)
188{
189	return (bus_space_read_1(h->sc->iot, h->sc->ioh, reg));
190}
191
192static __inline int tcic_read_2(struct tcic_handle *, int);
193static __inline int
194tcic_read_2(struct tcic_handle *h, int reg)
195{
196	return (bus_space_read_2(h->sc->iot, h->sc->ioh, reg));
197}
198
199static __inline int tcic_read_4(struct tcic_handle *, int);
200static __inline int
201tcic_read_4(struct tcic_handle *h, int reg)
202{
203	int val;
204	val = bus_space_read_2(h->sc->iot, h->sc->ioh, reg);
205	val |= bus_space_read_2(h->sc->iot, h->sc->ioh, reg+2) << 16;
206	return val;
207}
208
209static __inline void tcic_write_1(struct tcic_handle *, int, int);
210static __inline void
211tcic_write_1(struct tcic_handle *h, int reg, int data)
212{
213	bus_space_write_1(h->sc->iot, h->sc->ioh, reg, (data));
214}
215
216static __inline void tcic_write_2(struct tcic_handle *, int, int);
217static __inline void
218tcic_write_2(struct tcic_handle *h, int reg, int data)
219{
220	bus_space_write_2(h->sc->iot, h->sc->ioh, reg, (data));
221}
222
223static __inline void tcic_write_4(struct tcic_handle *, int, int);
224static __inline void
225tcic_write_4(struct tcic_handle *h, int reg, int data)
226{
227	bus_space_write_2(h->sc->iot, h->sc->ioh, reg, (data));
228	bus_space_write_2(h->sc->iot, h->sc->ioh, reg+2, (data)>>16);
229}
230
231static __inline int tcic_read_ind_2(struct tcic_handle *, int);
232static __inline int
233tcic_read_ind_2(struct tcic_handle *h, int reg)
234{
235	int r_addr, val;
236	r_addr = tcic_read_4(h, TCIC_R_ADDR);
237	tcic_write_4(h, TCIC_R_ADDR, reg|TCIC_ADDR_INDREG);
238	val = bus_space_read_2(h->sc->iot, h->sc->ioh, TCIC_R_DATA);
239	tcic_write_4(h, TCIC_R_ADDR, r_addr);
240	return val;
241}
242
243static __inline void tcic_write_ind_2(struct tcic_handle *, int, int);
244static __inline void
245tcic_write_ind_2(struct tcic_handle *h, int reg, int data)
246{
247	int r_addr;
248	r_addr = tcic_read_4(h, TCIC_R_ADDR);
249	tcic_write_4(h, TCIC_R_ADDR, reg|TCIC_ADDR_INDREG);
250	bus_space_write_2(h->sc->iot, h->sc->ioh, TCIC_R_DATA, (data));
251	tcic_write_4(h, TCIC_R_ADDR, r_addr);
252}
253
254static __inline void tcic_sel_sock(struct tcic_handle *);
255static __inline void
256tcic_sel_sock(struct tcic_handle *h)
257{
258	int r_addr;
259	r_addr = tcic_read_2(h, TCIC_R_ADDR2);
260	tcic_write_2(h, TCIC_R_ADDR2,
261	    (h->sock<<TCIC_ADDR2_SS_SHFT)|(r_addr & ~TCIC_ADDR2_SS_MASK));
262}
263
264static __inline void tcic_wait_ready(struct tcic_handle *);
265static __inline void
266tcic_wait_ready(struct tcic_handle *h)
267{
268	int i;
269
270	/* XXX appropriate socket must have been selected already. */
271	for (i = 0; i < 10000; i++) {
272		if (tcic_read_1(h, TCIC_R_SSTAT) & TCIC_SSTAT_RDY)
273			return;
274		delay(500);
275	}
276
277#ifdef DIAGNOSTIC
278	printf("tcic_wait_ready ready never happened\n");
279#endif
280}
281
282static __inline int tcic_read_aux_1(bus_space_tag_t, bus_space_handle_t, int, int);
283static __inline int
284tcic_read_aux_1(bus_space_tag_t iot, bus_space_handle_t ioh, int auxreg, int reg)
285{
286	int mode, val;
287	mode = bus_space_read_1(iot, ioh, TCIC_R_MODE);
288	bus_space_write_1(iot, ioh, TCIC_R_MODE, (mode & ~TCIC_AR_MASK)|auxreg);
289	val = bus_space_read_1(iot, ioh, reg);
290	return val;
291}
292
293static __inline int tcic_read_aux_2(bus_space_tag_t, bus_space_handle_t, int);
294static __inline int
295tcic_read_aux_2(bus_space_tag_t iot, bus_space_handle_t ioh, int auxreg)
296{
297	int mode, val;
298	mode = bus_space_read_1(iot, ioh, TCIC_R_MODE);
299	bus_space_write_1(iot, ioh, TCIC_R_MODE, (mode & ~TCIC_AR_MASK)|auxreg);
300	val = bus_space_read_2(iot, ioh, TCIC_R_AUX);
301	return val;
302}
303
304static __inline void tcic_write_aux_1(bus_space_tag_t, bus_space_handle_t, int, int, int);
305static __inline void
306tcic_write_aux_1(bus_space_tag_t iot, bus_space_handle_t ioh, int auxreg, int reg, int val)
307{
308	int mode;
309	mode = bus_space_read_1(iot, ioh, TCIC_R_MODE);
310	bus_space_write_1(iot, ioh, TCIC_R_MODE, (mode & ~TCIC_AR_MASK)|auxreg);
311	bus_space_write_1(iot, ioh, reg, val);
312}
313
314static __inline void tcic_write_aux_2(bus_space_tag_t, bus_space_handle_t, int, int);
315static __inline void
316tcic_write_aux_2(bus_space_tag_t iot, bus_space_handle_t ioh, int auxreg, int val)
317{
318	int mode;
319	mode = bus_space_read_1(iot, ioh, TCIC_R_MODE);
320	bus_space_write_1(iot, ioh, TCIC_R_MODE, (mode & ~TCIC_AR_MASK)|auxreg);
321	bus_space_write_2(iot, ioh, TCIC_R_AUX, val);
322}
323
324#endif	/* _TCIC2VAR_H */
325