igma.c revision 1.4.10.1 1 1.4.10.1 thorpej /* $NetBSD: igma.c,v 1.4.10.1 2021/04/02 22:17:44 thorpej Exp $ */
2 1.1 mlelstv
3 1.1 mlelstv /*
4 1.1 mlelstv * Copyright (c) 2014 Michael van Elst
5 1.1 mlelstv *
6 1.1 mlelstv * Permission to use, copy, modify, and distribute this software for any
7 1.1 mlelstv * purpose with or without fee is hereby granted, provided that the above
8 1.1 mlelstv * copyright notice and this permission notice appear in all copies.
9 1.1 mlelstv *
10 1.1 mlelstv * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 1.1 mlelstv * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 1.1 mlelstv * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 1.1 mlelstv * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 1.1 mlelstv * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 1.1 mlelstv * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 1.1 mlelstv * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 1.1 mlelstv */
18 1.1 mlelstv
19 1.1 mlelstv /*
20 1.1 mlelstv * Intel Graphic Media Accelerator
21 1.1 mlelstv */
22 1.1 mlelstv
23 1.1 mlelstv #include <sys/cdefs.h>
24 1.4.10.1 thorpej __KERNEL_RCSID(0, "$NetBSD: igma.c,v 1.4.10.1 2021/04/02 22:17:44 thorpej Exp $");
25 1.1 mlelstv
26 1.1 mlelstv #include "vga.h"
27 1.1 mlelstv
28 1.1 mlelstv #include <sys/param.h>
29 1.1 mlelstv #include <sys/systm.h>
30 1.1 mlelstv #include <sys/device.h>
31 1.1 mlelstv #include <sys/bus.h>
32 1.1 mlelstv
33 1.1 mlelstv #include <dev/pci/pcireg.h>
34 1.1 mlelstv #include <dev/pci/pcivar.h>
35 1.1 mlelstv #include <dev/pci/pcidevs.h>
36 1.1 mlelstv #include <dev/pci/pciio.h>
37 1.1 mlelstv
38 1.1 mlelstv #include <dev/i2c/i2cvar.h>
39 1.1 mlelstv #include <dev/i2c/i2c_bitbang.h>
40 1.1 mlelstv #include <dev/i2c/ddcvar.h>
41 1.1 mlelstv
42 1.1 mlelstv #include <dev/videomode/videomode.h>
43 1.1 mlelstv #include <dev/videomode/edidvar.h>
44 1.1 mlelstv
45 1.1 mlelstv #include <dev/wscons/wsdisplayvar.h>
46 1.1 mlelstv
47 1.1 mlelstv #if NVGA > 0
48 1.1 mlelstv #include <dev/ic/mc6845reg.h>
49 1.1 mlelstv #include <dev/ic/pcdisplayvar.h>
50 1.1 mlelstv #include <dev/ic/vgareg.h>
51 1.1 mlelstv #include <dev/ic/vgavar.h>
52 1.1 mlelstv #endif
53 1.1 mlelstv
54 1.1 mlelstv #include <dev/pci/igmareg.h>
55 1.1 mlelstv #include <dev/pci/igmavar.h>
56 1.1 mlelstv
57 1.1 mlelstv #include "igmafb.h"
58 1.1 mlelstv
59 1.1 mlelstv struct igma_softc;
60 1.1 mlelstv struct igma_i2c {
61 1.1 mlelstv struct igma_softc *ii_sc;
62 1.1 mlelstv bus_addr_t ii_reg;
63 1.1 mlelstv struct i2c_controller ii_i2c;
64 1.1 mlelstv const char *ii_name;
65 1.1 mlelstv u_int32_t ii_dir;
66 1.1 mlelstv };
67 1.1 mlelstv
68 1.1 mlelstv struct igma_softc {
69 1.1 mlelstv device_t sc_dev;
70 1.1 mlelstv struct igma_chip sc_chip;
71 1.1 mlelstv struct igma_i2c sc_ii[GMBUS_NUM_PORTS];
72 1.1 mlelstv };
73 1.1 mlelstv
74 1.1 mlelstv static int igma_match(device_t, cfdata_t, void *);
75 1.1 mlelstv static void igma_attach(device_t, device_t, void *);
76 1.1 mlelstv static int igma_print(void *, const char *);
77 1.1 mlelstv
78 1.1 mlelstv static void igma_i2c_attach(struct igma_softc *);
79 1.1 mlelstv
80 1.1 mlelstv CFATTACH_DECL_NEW(igma, sizeof(struct igma_softc),
81 1.1 mlelstv igma_match, igma_attach, NULL, NULL);
82 1.1 mlelstv
83 1.1 mlelstv static int igma_i2c_acquire_bus(void *, int);
84 1.1 mlelstv static void igma_i2c_release_bus(void *, int);
85 1.1 mlelstv static int igma_i2c_send_start(void *, int);
86 1.1 mlelstv static int igma_i2c_send_stop(void *, int);
87 1.1 mlelstv static int igma_i2c_initiate_xfer(void *, i2c_addr_t, int);
88 1.1 mlelstv static int igma_i2c_read_byte(void *, uint8_t *, int);
89 1.1 mlelstv static int igma_i2c_write_byte(void *, uint8_t, int);
90 1.1 mlelstv static void igma_i2cbb_set_bits(void *, uint32_t);
91 1.1 mlelstv static void igma_i2cbb_set_dir(void *, uint32_t);
92 1.1 mlelstv static uint32_t igma_i2cbb_read(void *);
93 1.1 mlelstv
94 1.1 mlelstv static void igma_reg_barrier(const struct igma_chip *, int);
95 1.1 mlelstv static u_int32_t igma_reg_read(const struct igma_chip *, int);
96 1.1 mlelstv static void igma_reg_write(const struct igma_chip *, int, u_int32_t);
97 1.1 mlelstv static u_int8_t igma_vga_read(const struct igma_chip *, int);
98 1.1 mlelstv static void igma_vga_write(const struct igma_chip *, int , u_int8_t);
99 1.1 mlelstv #if 0
100 1.1 mlelstv static u_int8_t igma_crtc_read(const struct igma_chip *, int);
101 1.1 mlelstv static void igma_crtc_write(const struct igma_chip *, int, u_int8_t);
102 1.1 mlelstv #endif
103 1.1 mlelstv
104 1.1 mlelstv static const struct i2c_bitbang_ops igma_i2cbb_ops = {
105 1.1 mlelstv igma_i2cbb_set_bits,
106 1.1 mlelstv igma_i2cbb_set_dir,
107 1.1 mlelstv igma_i2cbb_read,
108 1.1 mlelstv { 1, 2, 0, 1 }
109 1.1 mlelstv };
110 1.1 mlelstv
111 1.1 mlelstv static const struct igma_chip_ops igma_bus_ops = {
112 1.1 mlelstv igma_reg_barrier,
113 1.1 mlelstv igma_reg_read,
114 1.1 mlelstv igma_reg_write,
115 1.1 mlelstv igma_vga_read,
116 1.1 mlelstv igma_vga_write,
117 1.1 mlelstv #if 0
118 1.1 mlelstv igma_crtc_read,
119 1.1 mlelstv igma_crtc_write,
120 1.1 mlelstv #endif
121 1.1 mlelstv };
122 1.1 mlelstv
123 1.1 mlelstv static struct igma_product {
124 1.1 mlelstv u_int16_t product;
125 1.1 mlelstv int gentype;
126 1.1 mlelstv int num_pipes;
127 1.1 mlelstv } const igma_products[] = {
128 1.1 mlelstv /* i830 */
129 1.1 mlelstv { PCI_PRODUCT_INTEL_82830MP_IV, 200,2 },
130 1.1 mlelstv /* i845g */
131 1.1 mlelstv { PCI_PRODUCT_INTEL_82845G_IGD, 200,2 },
132 1.1 mlelstv /* i85x */
133 1.1 mlelstv { PCI_PRODUCT_INTEL_82855GM_IGD, 200,2 },
134 1.1 mlelstv // 0x358e ?
135 1.1 mlelstv /* i865g */
136 1.1 mlelstv { PCI_PRODUCT_INTEL_82865_IGD, 200,2 },
137 1.1 mlelstv /* i915g */
138 1.1 mlelstv { PCI_PRODUCT_INTEL_82915G_IGD, 200,2 },
139 1.1 mlelstv { PCI_PRODUCT_INTEL_E7221_IGD, 200,2 },
140 1.1 mlelstv /* i915gm */
141 1.1 mlelstv { PCI_PRODUCT_INTEL_82915GM_IGD, 300,2 },
142 1.1 mlelstv /* i945g */
143 1.1 mlelstv { PCI_PRODUCT_INTEL_82945P_IGD, 300,2 },
144 1.1 mlelstv /* i945gm */
145 1.1 mlelstv { PCI_PRODUCT_INTEL_82945GM_IGD, 300,2 },
146 1.1 mlelstv { PCI_PRODUCT_INTEL_82945GM_IGD_1, 300,2 },
147 1.1 mlelstv { PCI_PRODUCT_INTEL_82945GME_IGD, 300,2 },
148 1.1 mlelstv /* i965g */
149 1.1 mlelstv { PCI_PRODUCT_INTEL_82946GZ_IGD, 300,2 },
150 1.1 mlelstv { PCI_PRODUCT_INTEL_82G35_IGD, 300,2 },
151 1.1 mlelstv { PCI_PRODUCT_INTEL_82G35_IGD_1, 300,2 },
152 1.1 mlelstv { PCI_PRODUCT_INTEL_82965Q_IGD, 300,2 },
153 1.1 mlelstv { PCI_PRODUCT_INTEL_82965Q_IGD_1, 300,2 },
154 1.1 mlelstv { PCI_PRODUCT_INTEL_82965G_IGD, 300,2 },
155 1.1 mlelstv { PCI_PRODUCT_INTEL_82965G_IGD_1, 300,2 },
156 1.1 mlelstv /* g33 */
157 1.1 mlelstv { PCI_PRODUCT_INTEL_82G33_IGD, 300,2 },
158 1.1 mlelstv { PCI_PRODUCT_INTEL_82G33_IGD_1, 300,2 },
159 1.1 mlelstv { PCI_PRODUCT_INTEL_82Q33_IGD, 300,2 },
160 1.1 mlelstv { PCI_PRODUCT_INTEL_82Q33_IGD_1, 300,2 },
161 1.1 mlelstv { PCI_PRODUCT_INTEL_82Q35_IGD, 300,2 },
162 1.1 mlelstv { PCI_PRODUCT_INTEL_82Q35_IGD_1, 300,2 },
163 1.1 mlelstv /* pineview */
164 1.1 mlelstv { PCI_PRODUCT_INTEL_PINEVIEW_IGD, 350,2 },
165 1.1 mlelstv { PCI_PRODUCT_INTEL_PINEVIEW_M_IGD, 350,2 },
166 1.1 mlelstv /* i965gm */
167 1.1 mlelstv { PCI_PRODUCT_INTEL_82965PM_IGD, 400,2 },
168 1.1 mlelstv { PCI_PRODUCT_INTEL_82965PM_IGD_1, 400,2 },
169 1.1 mlelstv { PCI_PRODUCT_INTEL_82965GME_IGD, 400,2 },
170 1.1 mlelstv /* gm45 */
171 1.1 mlelstv { PCI_PRODUCT_INTEL_82GM45_IGD, 450,2 },
172 1.1 mlelstv { PCI_PRODUCT_INTEL_82GM45_IGD_1, 450,2 },
173 1.1 mlelstv /* g45 */
174 1.1 mlelstv { PCI_PRODUCT_INTEL_82IGD_E_IGD, 450,2 },
175 1.1 mlelstv { PCI_PRODUCT_INTEL_82Q45_IGD, 450,2 },
176 1.1 mlelstv { PCI_PRODUCT_INTEL_82G45_IGD, 450,2 },
177 1.1 mlelstv { PCI_PRODUCT_INTEL_82G41_IGD, 450,2 },
178 1.1 mlelstv { PCI_PRODUCT_INTEL_82B43_IGD, 450,2 },
179 1.1 mlelstv // 0x2e92 ?
180 1.1 mlelstv /* ironlake d */
181 1.1 mlelstv { PCI_PRODUCT_INTEL_IRONLAKE_D_IGD, 500,2 },
182 1.1 mlelstv /* ironlake m */
183 1.1 mlelstv { PCI_PRODUCT_INTEL_IRONLAKE_M_IGD, 500,2 },
184 1.1 mlelstv /* sandy bridge */
185 1.1 mlelstv { PCI_PRODUCT_INTEL_SANDYBRIDGE_IGD, 600,2 },
186 1.1 mlelstv { PCI_PRODUCT_INTEL_SANDYBRIDGE_IGD_1, 600,2 },
187 1.1 mlelstv { PCI_PRODUCT_INTEL_SANDYBRIDGE_IGD_2, 600,2 },
188 1.1 mlelstv /* sandy bridge m */
189 1.1 mlelstv { PCI_PRODUCT_INTEL_SANDYBRIDGE_M_IGD, 600,2 },
190 1.1 mlelstv { PCI_PRODUCT_INTEL_SANDYBRIDGE_M_IGD_1, 600,2 },
191 1.1 mlelstv { PCI_PRODUCT_INTEL_SANDYBRIDGE_M_IGD_2, 600,2 },
192 1.1 mlelstv /* sandy bridge s */
193 1.1 mlelstv { PCI_PRODUCT_INTEL_SANDYBRIDGE_S_IGD, 600,2 },
194 1.1 mlelstv /* ivy bridge */
195 1.1 mlelstv { PCI_PRODUCT_INTEL_IVYBRIDGE_IGD, 700,3 },
196 1.1 mlelstv { PCI_PRODUCT_INTEL_IVYBRIDGE_IGD_1, 700,3 },
197 1.1 mlelstv /* ivy bridge m */
198 1.1 mlelstv { PCI_PRODUCT_INTEL_IVYBRIDGE_M_IGD, 700,3 },
199 1.1 mlelstv { PCI_PRODUCT_INTEL_IVYBRIDGE_M_IGD_1, 700,3 },
200 1.1 mlelstv /* ivy bridge s */
201 1.1 mlelstv { PCI_PRODUCT_INTEL_IVYBRIDGE_S_IGD, 700,3 },
202 1.1 mlelstv { PCI_PRODUCT_INTEL_IVYBRIDGE_S_IGD_1, 700,3 },
203 1.1 mlelstv #if 0
204 1.1 mlelstv /* valleyview d */
205 1.1 mlelstv /* valleyview m */
206 1.1 mlelstv { PCI_PRODUCT_INTEL_HASWELL_IGD_1, 800,3 },
207 1.1 mlelstv /* haswell d */
208 1.1 mlelstv { PCI_PRODUCT_INTEL_HASWELL_IGD, 800,3 },
209 1.1 mlelstv { PCI_PRODUCT_INTEL_HASWELL_IGD_1, 800,3 },
210 1.1 mlelstv /* haswell m */
211 1.1 mlelstv /* broadwell d */
212 1.1 mlelstv /* broadwell m */
213 1.1 mlelstv #endif
214 1.1 mlelstv };
215 1.1 mlelstv
216 1.1 mlelstv static int
217 1.1 mlelstv igma_newpch_match(const struct pci_attach_args *pa)
218 1.1 mlelstv {
219 1.1 mlelstv if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
220 1.1 mlelstv return 0;
221 1.1 mlelstv switch (0xff00 & PCI_PRODUCT(pa->pa_id)) {
222 1.1 mlelstv case 0x3b00: /* ibex peak */
223 1.1 mlelstv case 0x1c00: /* cougar point */
224 1.1 mlelstv case 0x1e00: /* panther point */
225 1.1 mlelstv case 0x8c00: /* lynx point */
226 1.1 mlelstv case 0x9c00: /* lynx point lp */
227 1.1 mlelstv return 1;
228 1.1 mlelstv }
229 1.1 mlelstv
230 1.1 mlelstv return 0;
231 1.1 mlelstv }
232 1.1 mlelstv
233 1.1 mlelstv static const struct igma_product *
234 1.1 mlelstv igma_lookup(const struct pci_attach_args *pa)
235 1.1 mlelstv {
236 1.1 mlelstv const struct igma_product *ip;
237 1.1 mlelstv int i;
238 1.1 mlelstv
239 1.1 mlelstv if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
240 1.1 mlelstv return NULL;
241 1.1 mlelstv for (i=0; i < __arraycount(igma_products); ++i) {
242 1.1 mlelstv ip = &igma_products[i];
243 1.1 mlelstv if (PCI_PRODUCT(pa->pa_id) == ip->product)
244 1.1 mlelstv return ip;
245 1.1 mlelstv }
246 1.1 mlelstv return NULL;
247 1.1 mlelstv }
248 1.1 mlelstv
249 1.1 mlelstv static void
250 1.1 mlelstv igma_product_to_chip(const struct pci_attach_args *pa, struct igma_chip *cd)
251 1.1 mlelstv {
252 1.1 mlelstv const struct igma_product *ip;
253 1.1 mlelstv struct pci_attach_args PA;
254 1.1 mlelstv
255 1.1 mlelstv ip = igma_lookup(pa);
256 1.1 mlelstv KASSERT(ip != NULL);
257 1.1 mlelstv
258 1.1 mlelstv cd->ops = &igma_bus_ops;
259 1.1 mlelstv cd->num_gmbus = 6;
260 1.1 mlelstv cd->num_pipes = ip->num_pipes;
261 1.1 mlelstv cd->quirks = 0;
262 1.1 mlelstv cd->backlight_factor = 1;
263 1.1 mlelstv
264 1.1 mlelstv cd->gpio_offset = OLD_GPIOA;
265 1.1 mlelstv cd->vga_cntrl = PCH_VGA_CNTRL;
266 1.1 mlelstv cd->backlight_cntrl = OLD_BLC_PWM_CTL;
267 1.1 mlelstv cd->backlight_cntrl2 = OLD_BLC_PWM_CTL2;
268 1.1 mlelstv
269 1.1 mlelstv PA = *pa;
270 1.1 mlelstv if (pci_find_device(&PA, igma_newpch_match)) {
271 1.1 mlelstv cd->gpio_offset = PCH_GPIOA;
272 1.1 mlelstv cd->vga_cntrl = CPU_VGA_CNTRL;
273 1.1 mlelstv cd->backlight_cntrl = CPU_BLC_PWM_CTL;
274 1.1 mlelstv cd->backlight_cntrl2 = CPU_BLC_PWM_CTL2;
275 1.1 mlelstv }
276 1.1 mlelstv
277 1.1 mlelstv switch (ip->gentype) {
278 1.1 mlelstv case 200:
279 1.1 mlelstv cd->backlight_factor = 2;
280 1.1 mlelstv break;
281 1.1 mlelstv case 300:
282 1.1 mlelstv case 350:
283 1.1 mlelstv cd->backlight_factor = 2;
284 1.1 mlelstv cd->quirks |= IGMA_PFITDISABLE_QUIRK;
285 1.1 mlelstv break;
286 1.1 mlelstv case 450:
287 1.1 mlelstv cd->pri_cntrl = PRI_CTRL_NOTRICKLE;
288 1.1 mlelstv cd->quirks |= IGMA_PLANESTART_QUIRK;
289 1.1 mlelstv break;
290 1.1 mlelstv default:
291 1.1 mlelstv cd->pri_cntrl = 0;
292 1.1 mlelstv break;
293 1.1 mlelstv }
294 1.1 mlelstv }
295 1.1 mlelstv
296 1.1 mlelstv static void
297 1.1 mlelstv igma_adjust_chip(struct igma_softc *sc, struct igma_chip *cd)
298 1.1 mlelstv {
299 1.1 mlelstv const struct igma_chip_ops *co = cd->ops;
300 1.1 mlelstv u_int32_t reg;
301 1.1 mlelstv
302 1.1 mlelstv reg = co->read_reg(cd, cd->vga_cntrl);
303 1.1 mlelstv if (reg & VGA_PIPE_B_SELECT)
304 1.1 mlelstv cd->use_pipe = 1;
305 1.1 mlelstv }
306 1.1 mlelstv
307 1.1 mlelstv static int
308 1.1 mlelstv igma_print(void *aux, const char *pnp)
309 1.1 mlelstv {
310 1.1 mlelstv if (pnp)
311 1.1 mlelstv aprint_normal("drm at %s", pnp);
312 1.1 mlelstv return (UNCONF);
313 1.1 mlelstv }
314 1.1 mlelstv
315 1.1 mlelstv static int
316 1.1 mlelstv igma_match(device_t parent, cfdata_t match, void *aux)
317 1.1 mlelstv {
318 1.1 mlelstv struct pci_attach_args *pa = (struct pci_attach_args *)aux;
319 1.1 mlelstv const struct igma_product *ip;
320 1.1 mlelstv
321 1.1 mlelstv if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
322 1.1 mlelstv return 0;
323 1.1 mlelstv
324 1.1 mlelstv ip = igma_lookup(pa);
325 1.1 mlelstv if (ip != NULL)
326 1.1 mlelstv return 100;
327 1.1 mlelstv
328 1.1 mlelstv return 0;
329 1.1 mlelstv }
330 1.1 mlelstv
331 1.1 mlelstv static void
332 1.1 mlelstv igma_attach(device_t parent, device_t self, void *aux)
333 1.1 mlelstv {
334 1.1 mlelstv struct igma_softc *sc = device_private(self);
335 1.1 mlelstv const struct pci_attach_args *pa = (struct pci_attach_args *)aux;
336 1.1 mlelstv struct igma_attach_args iaa;
337 1.1 mlelstv bus_space_tag_t gttmmt, gmt, regt;
338 1.1 mlelstv bus_space_handle_t gttmmh, gmh, regh;
339 1.1 mlelstv bus_addr_t gttmmb, gmb;
340 1.1 mlelstv
341 1.1 mlelstv pci_aprint_devinfo(pa, NULL);
342 1.1 mlelstv
343 1.1 mlelstv sc->sc_dev = self;
344 1.1 mlelstv
345 1.1 mlelstv /* Initialize according to chip type */
346 1.1 mlelstv igma_product_to_chip(pa, &sc->sc_chip);
347 1.1 mlelstv
348 1.1 mlelstv if (pci_mapreg_map(pa, PCI_BAR0, PCI_MAPREG_TYPE_MEM,
349 1.1 mlelstv BUS_SPACE_MAP_LINEAR,
350 1.1 mlelstv >tmmt, >tmmh, >tmmb, NULL)) {
351 1.1 mlelstv aprint_error_dev(sc->sc_dev, "unable to map GTTMM\n");
352 1.1 mlelstv return;
353 1.1 mlelstv }
354 1.1 mlelstv sc->sc_chip.mmiot = gttmmt;
355 1.1 mlelstv if (bus_space_subregion(gttmmt, gttmmh, 0, 2*1024*1024,
356 1.1 mlelstv &sc->sc_chip.mmioh)) {
357 1.1 mlelstv aprint_error_dev(sc->sc_dev, "unable to submap MMIO\n");
358 1.1 mlelstv return;
359 1.1 mlelstv }
360 1.1 mlelstv sc->sc_chip.gttt = gttmmt;
361 1.1 mlelstv if (bus_space_subregion(gttmmt, gttmmh, 2*1024*1024, 2*1024*1024,
362 1.1 mlelstv &sc->sc_chip.gtth)) {
363 1.1 mlelstv aprint_error_dev(sc->sc_dev, "unable to submap GTT\n");
364 1.1 mlelstv return;
365 1.1 mlelstv }
366 1.1 mlelstv
367 1.1 mlelstv if (pci_mapreg_map(pa, PCI_BAR2, PCI_MAPREG_TYPE_MEM,
368 1.1 mlelstv BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE,
369 1.1 mlelstv &gmt, &gmh, &gmb, NULL)) {
370 1.1 mlelstv aprint_error_dev(sc->sc_dev, "unable to map aperture\n");
371 1.1 mlelstv return;
372 1.1 mlelstv }
373 1.1 mlelstv sc->sc_chip.gmt = gmt;
374 1.1 mlelstv sc->sc_chip.gmh = gmh;
375 1.1 mlelstv sc->sc_chip.gmb = gmb;
376 1.1 mlelstv
377 1.1 mlelstv if (pci_mapreg_map(pa, PCI_BAR4, PCI_MAPREG_TYPE_IO, 0,
378 1.1 mlelstv ®t, ®h, NULL, NULL)) {
379 1.1 mlelstv aprint_error_dev(sc->sc_dev, "unable to map IO registers\n");
380 1.1 mlelstv return;
381 1.1 mlelstv }
382 1.1 mlelstv
383 1.1 mlelstv #if NVGA > 0
384 1.1 mlelstv iaa.iaa_console = vga_cndetach() ? true : false;
385 1.1 mlelstv #else
386 1.1 mlelstv iaa.iaa_console = 0;
387 1.1 mlelstv #endif
388 1.1 mlelstv sc->sc_chip.vgat = regt;
389 1.1 mlelstv if (bus_space_map(regt, 0x3c0, 0x10, 0, &sc->sc_chip.vgah)) {
390 1.1 mlelstv aprint_error_dev(sc->sc_dev, "unable to map VGA registers\n");
391 1.1 mlelstv return;
392 1.1 mlelstv }
393 1.1 mlelstv
394 1.1 mlelstv /* Check hardware for more information */
395 1.1 mlelstv igma_adjust_chip(sc, &sc->sc_chip);
396 1.1 mlelstv
397 1.1 mlelstv aprint_normal("%s: VGA_CNTRL: 0x%x\n",device_xname(sc->sc_dev),
398 1.1 mlelstv sc->sc_chip.vga_cntrl);
399 1.1 mlelstv aprint_normal("%s: GPIO_OFFSET: 0x%x\n",device_xname(sc->sc_dev),
400 1.1 mlelstv sc->sc_chip.gpio_offset);
401 1.1 mlelstv aprint_normal("%s: BACKLIGHT_CTRL: 0x%x\n",device_xname(sc->sc_dev),
402 1.1 mlelstv sc->sc_chip.backlight_cntrl);
403 1.1 mlelstv aprint_normal("%s: BACKLIGHT_CTRL2: 0x%x\n",device_xname(sc->sc_dev),
404 1.1 mlelstv sc->sc_chip.backlight_cntrl2);
405 1.1 mlelstv
406 1.1 mlelstv #if NIGMAFB > 0
407 1.1 mlelstv strcpy(iaa.iaa_name, "igmafb");
408 1.1 mlelstv iaa.iaa_chip = sc->sc_chip;
409 1.4.10.1 thorpej config_found(sc->sc_dev, &iaa, igma_print,
410 1.4.10.1 thorpej CFARG_IATTR, "igmabus",
411 1.4.10.1 thorpej CFARG_EOL);
412 1.1 mlelstv #endif
413 1.1 mlelstv
414 1.1 mlelstv igma_i2c_attach(sc);
415 1.1 mlelstv }
416 1.1 mlelstv
417 1.1 mlelstv static void
418 1.1 mlelstv igma_i2c_attach(struct igma_softc *sc)
419 1.1 mlelstv {
420 1.1 mlelstv struct igma_i2c *ii;
421 1.1 mlelstv int i;
422 1.1 mlelstv #if 0
423 1.1 mlelstv struct i2cbus_attach_args iba;
424 1.1 mlelstv #endif
425 1.1 mlelstv
426 1.1 mlelstv for (i=0; i<sc->sc_chip.num_gmbus; ++i) {
427 1.1 mlelstv ii = &sc->sc_ii[i];
428 1.1 mlelstv ii->ii_sc = sc;
429 1.1 mlelstv
430 1.1 mlelstv /* XXX */
431 1.1 mlelstv ii->ii_reg = sc->sc_chip.gpio_offset - PCH_GPIOA;
432 1.1 mlelstv switch (i) {
433 1.1 mlelstv case 0:
434 1.1 mlelstv ii->ii_reg += PCH_GPIOB;
435 1.1 mlelstv ii->ii_name = "ssc";
436 1.1 mlelstv break;
437 1.1 mlelstv case 1:
438 1.1 mlelstv ii->ii_reg += PCH_GPIOA;
439 1.1 mlelstv ii->ii_name = "vga";
440 1.1 mlelstv break;
441 1.1 mlelstv case 2:
442 1.1 mlelstv ii->ii_reg += PCH_GPIOC;
443 1.1 mlelstv ii->ii_name = "panel";
444 1.1 mlelstv break;
445 1.1 mlelstv case 3:
446 1.1 mlelstv ii->ii_reg += PCH_GPIOD;
447 1.1 mlelstv ii->ii_name = "dpc";
448 1.1 mlelstv break;
449 1.1 mlelstv case 4:
450 1.1 mlelstv ii->ii_reg += PCH_GPIOE;
451 1.1 mlelstv ii->ii_name = "dpb";
452 1.1 mlelstv break;
453 1.1 mlelstv case 5:
454 1.1 mlelstv ii->ii_reg += PCH_GPIOF;
455 1.1 mlelstv ii->ii_name = "dpd";
456 1.1 mlelstv break;
457 1.1 mlelstv default:
458 1.1 mlelstv panic("don't know GMBUS %d\n",i);
459 1.1 mlelstv }
460 1.1 mlelstv
461 1.4 thorpej iic_tag_init(&ii->ii_i2c);
462 1.1 mlelstv ii->ii_i2c.ic_cookie = ii;
463 1.1 mlelstv ii->ii_i2c.ic_send_start = igma_i2c_send_start;
464 1.1 mlelstv ii->ii_i2c.ic_send_stop = igma_i2c_send_stop;
465 1.1 mlelstv ii->ii_i2c.ic_initiate_xfer = igma_i2c_initiate_xfer;
466 1.1 mlelstv ii->ii_i2c.ic_read_byte = igma_i2c_read_byte;
467 1.1 mlelstv ii->ii_i2c.ic_write_byte = igma_i2c_write_byte;
468 1.1 mlelstv
469 1.1 mlelstv #if 0
470 1.3 chs memset(&iba, 0, sizeof(iba));
471 1.1 mlelstv iba.iba_tag = &ii->ii_i2c;
472 1.4.10.1 thorpej config_found(sc->sc_dev, &iba, iicbus_print,
473 1.4.10.1 thorpej CFARG_IATTR, "i2cbus",
474 1.4.10.1 thorpej CFARG_EOL);
475 1.1 mlelstv #endif
476 1.1 mlelstv }
477 1.1 mlelstv }
478 1.1 mlelstv
479 1.1 mlelstv /*
480 1.1 mlelstv * I2C interface
481 1.1 mlelstv */
482 1.1 mlelstv
483 1.1 mlelstv static int
484 1.1 mlelstv igma_i2c_send_start(void *cookie, int flags)
485 1.1 mlelstv {
486 1.1 mlelstv return i2c_bitbang_send_start(cookie, flags, &igma_i2cbb_ops);
487 1.1 mlelstv }
488 1.1 mlelstv
489 1.1 mlelstv static int
490 1.1 mlelstv igma_i2c_send_stop(void *cookie, int flags)
491 1.1 mlelstv {
492 1.1 mlelstv return i2c_bitbang_send_stop(cookie, flags, &igma_i2cbb_ops);
493 1.1 mlelstv }
494 1.1 mlelstv
495 1.1 mlelstv static int
496 1.1 mlelstv igma_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
497 1.1 mlelstv {
498 1.1 mlelstv return i2c_bitbang_initiate_xfer(cookie, addr, flags, &igma_i2cbb_ops);
499 1.1 mlelstv }
500 1.1 mlelstv
501 1.1 mlelstv static int
502 1.1 mlelstv igma_i2c_read_byte(void *cookie, uint8_t *valp, int flags)
503 1.1 mlelstv {
504 1.1 mlelstv return i2c_bitbang_read_byte(cookie, valp, flags, &igma_i2cbb_ops);
505 1.1 mlelstv }
506 1.1 mlelstv
507 1.1 mlelstv static int
508 1.1 mlelstv igma_i2c_write_byte(void *cookie, uint8_t val, int flags)
509 1.1 mlelstv {
510 1.1 mlelstv return i2c_bitbang_write_byte(cookie, val, flags, &igma_i2cbb_ops);
511 1.1 mlelstv }
512 1.1 mlelstv
513 1.1 mlelstv static void
514 1.1 mlelstv igma_i2cbb_set_bits(void *cookie, uint32_t bits)
515 1.1 mlelstv {
516 1.1 mlelstv struct igma_i2c *ii = cookie;
517 1.1 mlelstv struct igma_softc *sc = ii->ii_sc;
518 1.1 mlelstv const struct igma_chip *cd = &sc->sc_chip;
519 1.1 mlelstv const struct igma_chip_ops *co = cd->ops;
520 1.1 mlelstv uint32_t reg;
521 1.1 mlelstv
522 1.1 mlelstv reg = co->read_reg(cd, ii->ii_reg);
523 1.1 mlelstv reg &= GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE;
524 1.1 mlelstv
525 1.1 mlelstv if ((bits | ii->ii_dir) & 1)
526 1.1 mlelstv /* make data input, signal is pulled high */
527 1.1 mlelstv reg |= GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
528 1.1 mlelstv else
529 1.1 mlelstv /* make data output, signal is driven low */
530 1.1 mlelstv reg |= GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK
531 1.1 mlelstv | GPIO_DATA_VAL_MASK;
532 1.1 mlelstv
533 1.1 mlelstv if (bits & 2)
534 1.1 mlelstv /* make clock input, signal is pulled high */
535 1.1 mlelstv reg |= GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
536 1.1 mlelstv else
537 1.1 mlelstv /* make clock output, signal is driven low */
538 1.1 mlelstv reg |= GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK
539 1.1 mlelstv | GPIO_CLOCK_VAL_MASK;
540 1.1 mlelstv
541 1.1 mlelstv co->write_reg(cd, ii->ii_reg, reg);
542 1.1 mlelstv #if 1
543 1.1 mlelstv reg = co->read_reg(cd, ii->ii_reg);
544 1.1 mlelstv #else
545 1.1 mlelstv co->barrier(cd, ii->ii_reg);
546 1.1 mlelstv #endif
547 1.1 mlelstv }
548 1.1 mlelstv
549 1.1 mlelstv static void
550 1.1 mlelstv igma_i2cbb_set_dir(void *cookie, uint32_t bits)
551 1.1 mlelstv {
552 1.1 mlelstv struct igma_i2c *ii = cookie;
553 1.1 mlelstv
554 1.1 mlelstv ii->ii_dir = bits;
555 1.1 mlelstv }
556 1.1 mlelstv
557 1.1 mlelstv static uint32_t
558 1.1 mlelstv igma_i2cbb_read(void *cookie)
559 1.1 mlelstv {
560 1.1 mlelstv struct igma_i2c *ii = cookie;
561 1.1 mlelstv struct igma_softc *sc = ii->ii_sc;
562 1.1 mlelstv const struct igma_chip *cd = &sc->sc_chip;
563 1.1 mlelstv const struct igma_chip_ops *co = cd->ops;
564 1.1 mlelstv uint32_t reg;
565 1.1 mlelstv int sda, scl;
566 1.1 mlelstv
567 1.1 mlelstv reg = co->read_reg(cd, ii->ii_reg);
568 1.1 mlelstv
569 1.1 mlelstv sda = reg & GPIO_DATA_VAL_IN;
570 1.1 mlelstv scl = reg & GPIO_CLOCK_VAL_IN;
571 1.1 mlelstv
572 1.1 mlelstv reg = (sda ? 1 : 0) | (scl ? 2 : 0);
573 1.1 mlelstv return reg;
574 1.1 mlelstv }
575 1.1 mlelstv
576 1.1 mlelstv static void
577 1.1 mlelstv igma_reg_barrier(const struct igma_chip *cd, int r)
578 1.1 mlelstv {
579 1.1 mlelstv bus_space_barrier(cd->mmiot, cd->mmioh, r, sizeof(u_int32_t),
580 1.1 mlelstv BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
581 1.1 mlelstv }
582 1.1 mlelstv
583 1.1 mlelstv static u_int32_t
584 1.1 mlelstv igma_reg_read(const struct igma_chip *cd, int r)
585 1.1 mlelstv {
586 1.1 mlelstv return bus_space_read_4(cd->mmiot, cd->mmioh, r);
587 1.1 mlelstv }
588 1.1 mlelstv
589 1.1 mlelstv static void
590 1.1 mlelstv igma_reg_write(const struct igma_chip *cd, int r, u_int32_t v)
591 1.1 mlelstv {
592 1.1 mlelstv bus_space_write_4(cd->mmiot, cd->mmioh, r, v);
593 1.1 mlelstv }
594 1.1 mlelstv
595 1.1 mlelstv static u_int8_t
596 1.1 mlelstv igma_vga_read(const struct igma_chip *cd, int r)
597 1.1 mlelstv {
598 1.1 mlelstv bus_space_write_1(cd->vgat, cd->vgah, 0x4, r | 0x20);
599 1.1 mlelstv return bus_space_read_1(cd->vgat, cd->vgah, 0x5);
600 1.1 mlelstv }
601 1.1 mlelstv
602 1.1 mlelstv static void
603 1.1 mlelstv igma_vga_write(const struct igma_chip *cd, int r, u_int8_t v)
604 1.1 mlelstv {
605 1.1 mlelstv bus_space_write_1(cd->vgat, cd->vgah, 0x4, r | 0x20);
606 1.1 mlelstv bus_space_write_1(cd->vgat, cd->vgah, 0x5, v);
607 1.1 mlelstv }
608 1.1 mlelstv
609 1.1 mlelstv #if 0
610 1.1 mlelstv static u_int8_t
611 1.1 mlelstv igma_crtc_read(const struct igma_chip *cd, int r)
612 1.1 mlelstv {
613 1.1 mlelstv bus_space_write_1(cd->crtct, cd->crtch, 0x4, r);
614 1.1 mlelstv return bus_space_read_1(cd->crtct, cd->crtch, 0x5);
615 1.1 mlelstv }
616 1.1 mlelstv
617 1.1 mlelstv static void
618 1.1 mlelstv igma_crtc_write(const struct igma_chip *cd, int r, u_int8_t v)
619 1.1 mlelstv {
620 1.1 mlelstv bus_space_write_1(cd->crtct, cd->crtch, 0x4, r);
621 1.1 mlelstv bus_space_write_1(cd->crtct, cd->crtch, 0x5, v);
622 1.1 mlelstv }
623 1.1 mlelstv #endif
624