xref: /netbsd/sys/dev/pci/pciide_opti_reg.h (revision bf9ec67e)
1 /*	$NetBSD: pciide_opti_reg.h,v 1.3 2001/10/21 18:49:20 thorpej Exp $	*/
2 
3 /*-
4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Steve C. Woodford.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Register definitions for OPTi PCIIDE controllers based on
41  * their 82c621 chip.
42  */
43 
44 /* IDE Initialization Control Register */
45 #define OPTI_REG_INIT_CONTROL		0x40
46 #define  OPTI_INIT_CONTROL_MODE_PIO_0	0
47 #define  OPTI_INIT_CONTROL_MODE_PIO_1	2
48 #define  OPTI_INIT_CONTROL_MODE_PIO_2	1
49 #define  OPTI_INIT_CONTROL_MODE_PIO_3	3
50 #define  OPTI_INIT_CONTROL_ADDR_RELOC	(1u << 2)
51 #define  OPTI_INIT_CONTROL_CH2_ENABLE	0
52 #define  OPTI_INIT_CONTROL_CH2_DISABLE	(1u << 3)
53 #define  OPTI_INIT_CONTROL_FIFO_16	0
54 #define  OPTI_INIT_CONTROL_FIFO_32	(1u << 5)
55 #define  OPTI_INIT_CONTROL_FIFO_REQ_32	0
56 #define  OPTI_INIT_CONTROL_FIFO_REQ_30	(1u << 6)
57 #define  OPTI_INIT_CONTROL_FIFO_REQ_28	(2u << 6)
58 #define  OPTI_INIT_CONTROL_FIFO_REQ_26	(3u << 6)
59 
60 /* IDE Enhanced Features Register */
61 #define OPTI_REG_ENH_FEAT		0x42
62 #define  OPTI_ENH_FEAT_X111_ENABLE	(1u << 1)
63 #define  OPTI_ENH_FEAT_CONCURRENT_MAST	(1u << 2)
64 #define  OPTI_ENH_FEAT_PCI_INVALIDATE	(1u << 3)
65 #define  OPTI_ENH_FEAT_IDE_CONCUR	(1u << 4)
66 #define  OPTI_ENH_FEAT_SLAVE_FIFO_ISA	(1u << 5)
67 
68 /* IDE Enhanced Mode Register */
69 #define OPTI_REG_ENH_MODE		0x43
70 #define  OPTI_ENH_MODE_MASK(c,d)	(3u << (((c) * 4) + ((d) * 2)))
71 #define  OPTI_ENH_MODE_USE_TIMING(c,d)	0
72 #define  OPTI_ENH_MODE(c,d,m)		((m) << (((c) * 4) + ((d) * 2)))
73 
74 /* Timing registers */
75 #define OPTI_REG_READ_CYCLE_TIMING	0x00
76 #define OPTI_REG_WRITE_CYCLE_TIMING	0x01
77 #define  OPTI_RECOVERY_TIME_SHIFT	0
78 #define  OPTI_PULSE_WIDTH_SHIFT		4
79 
80 /*
81  * Control register.
82  */
83 #define OPTI_REG_CONTROL		0x03
84 #define  OPTI_CONTROL_DISABLE		0x11
85 #define  OPTI_CONTROL_ENABLE		0x95
86 
87 /* Strap register */
88 #define OPTI_REG_STRAP			0x05
89 #define  OPTI_STRAP_PCI_SPEED_MASK	0x1u
90 #define  OPTI_STRAP_PCI_33		0
91 #define  OPTI_STRAP_PCI_25		1
92 
93 /* Miscellaneous register */
94 #define OPTI_REG_MISC			0x06
95 #define  OPTI_MISC_INDEX(d)		((unsigned)(d))
96 #define  OPTI_MISC_INDEX_MASK		0x01u
97 #define  OPTI_MISC_DELAY_MASK		0x07u
98 #define  OPTI_MISC_DELAY_SHIFT		1
99 #define  OPTI_MISC_ADDR_SETUP_MASK	0x3u
100 #define  OPTI_MISC_ADDR_SETUP_SHIFT	4
101 #define  OPTI_MISC_READ_PREFETCH_ENABLE	(1u << 6)
102 #define  OPTI_MISC_ADDR_SETUP_MASK	0x3u
103 #define  OPTI_MISC_WRITE_MASK		0x7fu
104 
105 
106 /*
107  * Inline functions for accessing the timing registers of the
108  * OPTi controller.
109  *
110  * These *MUST* disable interrupts as they need atomic access to
111  * certain magic registers. Failure to adhere to this *will*
112  * break things in subtle ways if the wdc registers are accessed
113  * by an interrupt routine while this magic sequence is executing.
114  */
115 static __inline__ u_int8_t __attribute__((__unused__))
116 opti_read_config(struct channel_softc *chp, int reg)
117 {
118 	u_int8_t rv;
119 	int s = splhigh();
120 
121 	/* Two consecutive 16-bit reads from register #1 (0x1f1/0x171) */
122 	(void) bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wd_features);
123 	(void) bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wd_features);
124 
125 	/* Followed by an 8-bit write of 0x3 to register #2 */
126 	bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, 0x03u);
127 
128 	/* Now we can read the required register */
129 	rv = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, reg);
130 
131 	/* Restore the real registers */
132 	bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, 0x83u);
133 
134 	splx(s);
135 
136 	return rv;
137 }
138 
139 static __inline__ void __attribute__((__unused__))
140 opti_write_config(struct channel_softc *chp, int reg, u_int8_t val)
141 {
142 	int s = splhigh();
143 
144 	/* Two consecutive 16-bit reads from register #1 (0x1f1/0x171) */
145 	(void) bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wd_features);
146 	(void) bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wd_features);
147 
148 	/* Followed by an 8-bit write of 0x3 to register #2 */
149 	bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, 0x03u);
150 
151 	/* Now we can write the required register */
152 	bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, reg, val);
153 
154 	/* Restore the real registers */
155 	bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, 0x83u);
156 
157 	splx(s);
158 }
159 
160 /*
161  * These are the timing register values for the various IDE modes
162  * supported by the OPTi chip. The first index of the two-dimensional
163  * arrays is used for a 33MHz PCIbus, the second for a 25MHz PCIbus.
164  */
165 static const u_int8_t opti_tim_cp[2][8] __attribute__((__unused__)) = {
166 	/* Command Pulse */
167 	{5, 4, 3, 2, 2, 7, 2, 2},
168 	{4, 3, 2, 2, 1, 5, 2, 1}
169 };
170 
171 static const u_int8_t opti_tim_rt[2][8] __attribute__((__unused__)) = {
172 	/* Recovery Time */
173 	{9, 4, 0, 0, 0, 6, 0, 0},
174 	{6, 2, 0, 0, 0, 4, 0, 0}
175 };
176 
177 static const u_int8_t opti_tim_as[2][8] __attribute__((__unused__)) = {
178 	/* Address Setup */
179 	{2, 1, 1, 1, 0, 0, 0, 0},
180 	{1, 1, 0, 0, 0, 0, 0, 0}
181 };
182 
183 static const u_int8_t opti_tim_em[8] __attribute__((__unused__)) = {
184 	/* Enhanced Mode */
185 	0, 0, 0, 1, 2, 0, 1 ,2
186 };
187