atiixp.c (f2a1d71aaaf95d8a26cad69f7f72bfe0f1b46027) atiixp.c (9f52a325cde5f950bc10616fffb823619cf88289)
1/*-
2 * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 51 unchanged lines hidden (view full) ---

60#include <dev/pci/pcivar.h>
61#include <sys/sysctl.h>
62#include <sys/endian.h>
63
64#include <dev/sound/pci/atiixp.h>
65
66SND_DECLARE_FILE("$FreeBSD$");
67
1/*-
2 * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 51 unchanged lines hidden (view full) ---

60#include <dev/pci/pcivar.h>
61#include <sys/sysctl.h>
62#include <sys/endian.h>
63
64#include <dev/sound/pci/atiixp.h>
65
66SND_DECLARE_FILE("$FreeBSD$");
67
68#define ATI_IXP_DMA_RETRY_MAX 100
69#define ATI_IXP_DMA_CHSEGS_DEFAULT 2
70
71#define ATI_IXP_BUFSZ_MIN 4096
72#define ATI_IXP_BUFSZ_MAX 65536
73#define ATI_IXP_BUFSZ_DEFAULT 16384
74
75#ifdef ATI_IXP_DEBUG_VERBOSE
76#undef ATI_IXP_DEBUG
77#define ATI_IXP_DEBUG 1
78#endif
79
68struct atiixp_dma_op {
69 volatile uint32_t addr;
70 volatile uint16_t status;
71 volatile uint16_t size;
72 volatile uint32_t next;
73};
74
75struct atiixp_info;
76
77struct atiixp_chinfo {
78 struct snd_dbuf *buffer;
79 struct pcm_channel *channel;
80 struct atiixp_info *parent;
81 struct atiixp_dma_op *sgd_table;
82 bus_addr_t sgd_addr;
83 uint32_t enable_bit, flush_bit, linkptr_bit, dma_dt_cur_bit;
80struct atiixp_dma_op {
81 volatile uint32_t addr;
82 volatile uint16_t status;
83 volatile uint16_t size;
84 volatile uint32_t next;
85};
86
87struct atiixp_info;
88
89struct atiixp_chinfo {
90 struct snd_dbuf *buffer;
91 struct pcm_channel *channel;
92 struct atiixp_info *parent;
93 struct atiixp_dma_op *sgd_table;
94 bus_addr_t sgd_addr;
95 uint32_t enable_bit, flush_bit, linkptr_bit, dma_dt_cur_bit;
84 uint32_t dma_segs;
96 uint32_t dma_segs, dma_blksz;
97#ifdef ATI_IXP_DEBUG
98 uint32_t dma_ptr, dma_prevptr;
99#endif
85 uint32_t fmt;
86 int caps_32bit, dir, active;
87};
88
89struct atiixp_info {
90 device_t dev;
91
92 bus_space_tag_t st;

--- 43 unchanged lines hidden (view full) ---

136
137static struct pcmchan_caps atiixp_caps_32bit = {
138 ATI_IXP_BASE_RATE,
139 ATI_IXP_BASE_RATE,
140 atiixp_fmt_32bit, 0
141};
142
143static struct pcmchan_caps atiixp_caps = {
100 uint32_t fmt;
101 int caps_32bit, dir, active;
102};
103
104struct atiixp_info {
105 device_t dev;
106
107 bus_space_tag_t st;

--- 43 unchanged lines hidden (view full) ---

151
152static struct pcmchan_caps atiixp_caps_32bit = {
153 ATI_IXP_BASE_RATE,
154 ATI_IXP_BASE_RATE,
155 atiixp_fmt_32bit, 0
156};
157
158static struct pcmchan_caps atiixp_caps = {
144 ATI_IXP_BASE_RATE,
145 ATI_IXP_BASE_RATE,
159 ATI_IXP_BASE_RATE,
160 ATI_IXP_BASE_RATE,
146 atiixp_fmt, 0
147};
148
149static const struct {
150 uint16_t vendor;
151 uint16_t devid;
152 char *desc;
153} atiixp_hw[] = {
154 { ATI_VENDOR_ID, ATI_IXP_200_ID, "ATI IXP 200" },
155 { ATI_VENDOR_ID, ATI_IXP_300_ID, "ATI IXP 300" },
156 { ATI_VENDOR_ID, ATI_IXP_400_ID, "ATI IXP 400" },
157};
158
159static void atiixp_enable_interrupts(struct atiixp_info *);
160static void atiixp_disable_interrupts(struct atiixp_info *);
161static void atiixp_reset_aclink(struct atiixp_info *);
161 atiixp_fmt, 0
162};
163
164static const struct {
165 uint16_t vendor;
166 uint16_t devid;
167 char *desc;
168} atiixp_hw[] = {
169 { ATI_VENDOR_ID, ATI_IXP_200_ID, "ATI IXP 200" },
170 { ATI_VENDOR_ID, ATI_IXP_300_ID, "ATI IXP 300" },
171 { ATI_VENDOR_ID, ATI_IXP_400_ID, "ATI IXP 400" },
172};
173
174static void atiixp_enable_interrupts(struct atiixp_info *);
175static void atiixp_disable_interrupts(struct atiixp_info *);
176static void atiixp_reset_aclink(struct atiixp_info *);
162static void atiixp_flush_dma(struct atiixp_info *, struct atiixp_chinfo *);
163static void atiixp_enable_dma(struct atiixp_info *, struct atiixp_chinfo *);
164static void atiixp_disable_dma(struct atiixp_info *, struct atiixp_chinfo *);
177static void atiixp_flush_dma(struct atiixp_chinfo *);
178static void atiixp_enable_dma(struct atiixp_chinfo *);
179static void atiixp_disable_dma(struct atiixp_chinfo *);
165
166static int atiixp_waitready_codec(struct atiixp_info *);
167static int atiixp_rdcd(kobj_t, void *, int);
168static int atiixp_wrcd(kobj_t, void *, int, uint32_t);
169
170static void *atiixp_chan_init(kobj_t, void *, struct snd_dbuf *,
171 struct pcm_channel *, int);
172static int atiixp_chan_setformat(kobj_t, void *, uint32_t);
173static int atiixp_chan_setspeed(kobj_t, void *, uint32_t);
174static int atiixp_chan_setblocksize(kobj_t, void *, uint32_t);
175static void atiixp_buildsgdt(struct atiixp_chinfo *);
176static int atiixp_chan_trigger(kobj_t, void *, int);
180
181static int atiixp_waitready_codec(struct atiixp_info *);
182static int atiixp_rdcd(kobj_t, void *, int);
183static int atiixp_wrcd(kobj_t, void *, int, uint32_t);
184
185static void *atiixp_chan_init(kobj_t, void *, struct snd_dbuf *,
186 struct pcm_channel *, int);
187static int atiixp_chan_setformat(kobj_t, void *, uint32_t);
188static int atiixp_chan_setspeed(kobj_t, void *, uint32_t);
189static int atiixp_chan_setblocksize(kobj_t, void *, uint32_t);
190static void atiixp_buildsgdt(struct atiixp_chinfo *);
191static int atiixp_chan_trigger(kobj_t, void *, int);
192static __inline uint32_t atiixp_dmapos(struct atiixp_chinfo *);
177static int atiixp_chan_getptr(kobj_t, void *);
178static struct pcmchan_caps *atiixp_chan_getcaps(kobj_t, void *);
179
180static void atiixp_intr(void *);
181static void atiixp_dma_cb(void *, bus_dma_segment_t *, int, int);
182static void atiixp_chip_pre_init(struct atiixp_info *);
183static void atiixp_chip_post_init(void *);
184static void atiixp_release_resource(struct atiixp_info *);

--- 18 unchanged lines hidden (view full) ---

203 value = atiixp_rd(sc, ATI_REG_IER);
204
205 value |= ATI_REG_IER_IO_STATUS_EN;
206
207 /*
208 * Disable / ignore internal xrun/spdf interrupt flags
209 * since it doesn't interest us (for now).
210 */
193static int atiixp_chan_getptr(kobj_t, void *);
194static struct pcmchan_caps *atiixp_chan_getcaps(kobj_t, void *);
195
196static void atiixp_intr(void *);
197static void atiixp_dma_cb(void *, bus_dma_segment_t *, int, int);
198static void atiixp_chip_pre_init(struct atiixp_info *);
199static void atiixp_chip_post_init(void *);
200static void atiixp_release_resource(struct atiixp_info *);

--- 18 unchanged lines hidden (view full) ---

219 value = atiixp_rd(sc, ATI_REG_IER);
220
221 value |= ATI_REG_IER_IO_STATUS_EN;
222
223 /*
224 * Disable / ignore internal xrun/spdf interrupt flags
225 * since it doesn't interest us (for now).
226 */
211#if 0
227#if 1
228 value &= ~(ATI_REG_IER_IN_XRUN_EN | ATI_REG_IER_OUT_XRUN_EN |
229 ATI_REG_IER_SPDF_XRUN_EN | ATI_REG_IER_SPDF_STATUS_EN);
230#else
212 value |= ATI_REG_IER_IN_XRUN_EN;
213 value |= ATI_REG_IER_OUT_XRUN_EN;
214
215 value |= ATI_REG_IER_SPDF_XRUN_EN;
216 value |= ATI_REG_IER_SPDF_STATUS_EN;
217#endif
218
219 atiixp_wr(sc, ATI_REG_IER, value);

--- 18 unchanged lines hidden (view full) ---

238 value = atiixp_rd(sc, ATI_REG_CMD);
239 if (value & ATI_REG_CMD_POWERDOWN) {
240 /* explicitly enable power */
241 value &= ~ATI_REG_CMD_POWERDOWN;
242 atiixp_wr(sc, ATI_REG_CMD, value);
243
244 /* have to wait at least 10 usec for it to initialise */
245 DELAY(20);
231 value |= ATI_REG_IER_IN_XRUN_EN;
232 value |= ATI_REG_IER_OUT_XRUN_EN;
233
234 value |= ATI_REG_IER_SPDF_XRUN_EN;
235 value |= ATI_REG_IER_SPDF_STATUS_EN;
236#endif
237
238 atiixp_wr(sc, ATI_REG_IER, value);

--- 18 unchanged lines hidden (view full) ---

257 value = atiixp_rd(sc, ATI_REG_CMD);
258 if (value & ATI_REG_CMD_POWERDOWN) {
259 /* explicitly enable power */
260 value &= ~ATI_REG_CMD_POWERDOWN;
261 atiixp_wr(sc, ATI_REG_CMD, value);
262
263 /* have to wait at least 10 usec for it to initialise */
264 DELAY(20);
246 };
265 }
247
248 /* perform a soft reset */
249 value = atiixp_rd(sc, ATI_REG_CMD);
250 value |= ATI_REG_CMD_AC_SOFT_RESET;
251 atiixp_wr(sc, ATI_REG_CMD, value);
252
253 /* need to read the CMD reg and wait aprox. 10 usec to init */
254 value = atiixp_rd(sc, ATI_REG_CMD);

--- 24 unchanged lines hidden (view full) ---

279
280 /* assert aclink reset again */
281 value = atiixp_rd(sc, ATI_REG_CMD);
282 value |= ATI_REG_CMD_AC_RESET;
283 atiixp_wr(sc, ATI_REG_CMD, value);
284
285 /* check if its active now */
286 value = atiixp_rd(sc, ATI_REG_CMD);
266
267 /* perform a soft reset */
268 value = atiixp_rd(sc, ATI_REG_CMD);
269 value |= ATI_REG_CMD_AC_SOFT_RESET;
270 atiixp_wr(sc, ATI_REG_CMD, value);
271
272 /* need to read the CMD reg and wait aprox. 10 usec to init */
273 value = atiixp_rd(sc, ATI_REG_CMD);

--- 24 unchanged lines hidden (view full) ---

298
299 /* assert aclink reset again */
300 value = atiixp_rd(sc, ATI_REG_CMD);
301 value |= ATI_REG_CMD_AC_RESET;
302 atiixp_wr(sc, ATI_REG_CMD, value);
303
304 /* check if its active now */
305 value = atiixp_rd(sc, ATI_REG_CMD);
287 };
306 }
288
289 if (timeout == 0)
290 device_printf(sc->dev, "giving up aclink reset\n");
291#if 0
292 if (timeout != 10)
293 device_printf(sc->dev, "aclink hardware reset successful\n");
294#endif
295
296 /* assert reset and sync for safety */
297 value = atiixp_rd(sc, ATI_REG_CMD);
298 value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET;
299 atiixp_wr(sc, ATI_REG_CMD, value);
300}
301
302static void
307
308 if (timeout == 0)
309 device_printf(sc->dev, "giving up aclink reset\n");
310#if 0
311 if (timeout != 10)
312 device_printf(sc->dev, "aclink hardware reset successful\n");
313#endif
314
315 /* assert reset and sync for safety */
316 value = atiixp_rd(sc, ATI_REG_CMD);
317 value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET;
318 atiixp_wr(sc, ATI_REG_CMD, value);
319}
320
321static void
303atiixp_flush_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
322atiixp_flush_dma(struct atiixp_chinfo *ch)
304{
323{
305 atiixp_wr(sc, ATI_REG_FIFO_FLUSH, ch->flush_bit);
324 atiixp_wr(ch->parent, ATI_REG_FIFO_FLUSH, ch->flush_bit);
306}
307
308static void
325}
326
327static void
309atiixp_enable_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
328atiixp_enable_dma(struct atiixp_chinfo *ch)
310{
311 uint32_t value;
312
329{
330 uint32_t value;
331
313 value = atiixp_rd(sc, ATI_REG_CMD);
332 value = atiixp_rd(ch->parent, ATI_REG_CMD);
314 if (!(value & ch->enable_bit)) {
315 value |= ch->enable_bit;
333 if (!(value & ch->enable_bit)) {
334 value |= ch->enable_bit;
316 atiixp_wr(sc, ATI_REG_CMD, value);
335 atiixp_wr(ch->parent, ATI_REG_CMD, value);
317 }
318}
319
336 }
337}
338
320static void
321atiixp_disable_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
339static void
340atiixp_disable_dma(struct atiixp_chinfo *ch)
322{
323 uint32_t value;
324
341{
342 uint32_t value;
343
325 value = atiixp_rd(sc, ATI_REG_CMD);
344 value = atiixp_rd(ch->parent, ATI_REG_CMD);
326 if (value & ch->enable_bit) {
327 value &= ~ch->enable_bit;
345 if (value & ch->enable_bit) {
346 value &= ~ch->enable_bit;
328 atiixp_wr(sc, ATI_REG_CMD, value);
347 atiixp_wr(ch->parent, ATI_REG_CMD, value);
329 }
330}
331
332/*
333 * AC97 interface
334 */
335static int
336atiixp_waitready_codec(struct atiixp_info *sc)
337{
338 int timeout = 500;
339
340 do {
341 if ((atiixp_rd(sc, ATI_REG_PHYS_OUT_ADDR) &
342 ATI_REG_PHYS_OUT_ADDR_EN) == 0)
348 }
349}
350
351/*
352 * AC97 interface
353 */
354static int
355atiixp_waitready_codec(struct atiixp_info *sc)
356{
357 int timeout = 500;
358
359 do {
360 if ((atiixp_rd(sc, ATI_REG_PHYS_OUT_ADDR) &
361 ATI_REG_PHYS_OUT_ADDR_EN) == 0)
343 return 0;
362 return (0);
344 DELAY(1);
363 DELAY(1);
345 } while (timeout--);
364 } while (--timeout);
346
365
347 return -1;
366 return (-1);
348}
349
350static int
351atiixp_rdcd(kobj_t obj, void *devinfo, int reg)
352{
353 struct atiixp_info *sc = devinfo;
354 uint32_t data;
355 int timeout;
356
357 if (atiixp_waitready_codec(sc))
367}
368
369static int
370atiixp_rdcd(kobj_t obj, void *devinfo, int reg)
371{
372 struct atiixp_info *sc = devinfo;
373 uint32_t data;
374 int timeout;
375
376 if (atiixp_waitready_codec(sc))
358 return -1;
377 return (-1);
359
360 data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
361 ATI_REG_PHYS_OUT_ADDR_EN |
362 ATI_REG_PHYS_OUT_RW | sc->codec_idx;
363
364 atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
365
366 if (atiixp_waitready_codec(sc))
378
379 data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
380 ATI_REG_PHYS_OUT_ADDR_EN |
381 ATI_REG_PHYS_OUT_RW | sc->codec_idx;
382
383 atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
384
385 if (atiixp_waitready_codec(sc))
367 return -1;
386 return (-1);
368
369 timeout = 500;
370 do {
371 data = atiixp_rd(sc, ATI_REG_PHYS_IN_ADDR);
372 if (data & ATI_REG_PHYS_IN_READ_FLAG)
387
388 timeout = 500;
389 do {
390 data = atiixp_rd(sc, ATI_REG_PHYS_IN_ADDR);
391 if (data & ATI_REG_PHYS_IN_READ_FLAG)
373 return data >> ATI_REG_PHYS_IN_DATA_SHIFT;
392 return (data >> ATI_REG_PHYS_IN_DATA_SHIFT);
374 DELAY(1);
393 DELAY(1);
375 } while (timeout--);
394 } while (--timeout);
376
377 if (reg < 0x7c)
378 device_printf(sc->dev, "codec read timeout! (reg 0x%x)\n", reg);
379
395
396 if (reg < 0x7c)
397 device_printf(sc->dev, "codec read timeout! (reg 0x%x)\n", reg);
398
380 return -1;
399 return (-1);
381}
382
383static int
384atiixp_wrcd(kobj_t obj, void *devinfo, int reg, uint32_t data)
385{
386 struct atiixp_info *sc = devinfo;
387
388 if (atiixp_waitready_codec(sc))
400}
401
402static int
403atiixp_wrcd(kobj_t obj, void *devinfo, int reg, uint32_t data)
404{
405 struct atiixp_info *sc = devinfo;
406
407 if (atiixp_waitready_codec(sc))
389 return -1;
408 return (-1);
390
391 data = (data << ATI_REG_PHYS_OUT_DATA_SHIFT) |
392 (((uint32_t)reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
393 ATI_REG_PHYS_OUT_ADDR_EN | sc->codec_idx;
394
395 atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
396
409
410 data = (data << ATI_REG_PHYS_OUT_DATA_SHIFT) |
411 (((uint32_t)reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
412 ATI_REG_PHYS_OUT_ADDR_EN | sc->codec_idx;
413
414 atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
415
397 return 0;
416 return (0);
398}
399
400static kobj_method_t atiixp_ac97_methods[] = {
401 KOBJMETHOD(ac97_read, atiixp_rdcd),
402 KOBJMETHOD(ac97_write, atiixp_wrcd),
403 { 0, 0 }
404};
405AC97_DECLARE(atiixp_ac97);

--- 29 unchanged lines hidden (view full) ---

435 ch->caps_32bit = 1;
436 }
437
438 ch->buffer = b;
439 ch->parent = sc;
440 ch->channel = c;
441 ch->dir = dir;
442 ch->dma_segs = sc->dma_segs;
417}
418
419static kobj_method_t atiixp_ac97_methods[] = {
420 KOBJMETHOD(ac97_read, atiixp_rdcd),
421 KOBJMETHOD(ac97_write, atiixp_wrcd),
422 { 0, 0 }
423};
424AC97_DECLARE(atiixp_ac97);

--- 29 unchanged lines hidden (view full) ---

454 ch->caps_32bit = 1;
455 }
456
457 ch->buffer = b;
458 ch->parent = sc;
459 ch->channel = c;
460 ch->dir = dir;
461 ch->dma_segs = sc->dma_segs;
462 ch->dma_blksz = sc->bufsz / sc->dma_segs;
443
444 atiixp_unlock(sc);
445
446 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1)
463
464 atiixp_unlock(sc);
465
466 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1)
447 return NULL;
467 return (NULL);
448
449 atiixp_lock(sc);
450 num = sc->registered_channels++;
451 ch->sgd_table = &sc->sgd_table[num * ch->dma_segs];
452 ch->sgd_addr = sc->sgd_addr +
453 (num * ch->dma_segs * sizeof(struct atiixp_dma_op));
468
469 atiixp_lock(sc);
470 num = sc->registered_channels++;
471 ch->sgd_table = &sc->sgd_table[num * ch->dma_segs];
472 ch->sgd_addr = sc->sgd_addr +
473 (num * ch->dma_segs * sizeof(struct atiixp_dma_op));
454 atiixp_disable_dma(sc, ch);
474 atiixp_disable_dma(ch);
455 atiixp_unlock(sc);
456
475 atiixp_unlock(sc);
476
457 return ch;
477 return (ch);
458}
459
460static int
461atiixp_chan_setformat(kobj_t obj, void *data, uint32_t format)
462{
463 struct atiixp_chinfo *ch = data;
464 struct atiixp_info *sc = ch->parent;
465 uint32_t value;

--- 20 unchanged lines hidden (view full) ---

486 atiixp_wr(sc, ATI_REG_CMD, value);
487 value = atiixp_rd(sc, ATI_REG_6CH_REORDER);
488 value &= ~ATI_REG_6CH_REORDER_EN;
489 atiixp_wr(sc, ATI_REG_6CH_REORDER, value);
490 }
491 ch->fmt = format;
492 atiixp_unlock(sc);
493
478}
479
480static int
481atiixp_chan_setformat(kobj_t obj, void *data, uint32_t format)
482{
483 struct atiixp_chinfo *ch = data;
484 struct atiixp_info *sc = ch->parent;
485 uint32_t value;

--- 20 unchanged lines hidden (view full) ---

506 atiixp_wr(sc, ATI_REG_CMD, value);
507 value = atiixp_rd(sc, ATI_REG_6CH_REORDER);
508 value &= ~ATI_REG_6CH_REORDER_EN;
509 atiixp_wr(sc, ATI_REG_6CH_REORDER, value);
510 }
511 ch->fmt = format;
512 atiixp_unlock(sc);
513
494 return 0;
514 return (0);
495}
496
497static int
498atiixp_chan_setspeed(kobj_t obj, void *data, uint32_t spd)
499{
500 /* XXX We're supposed to do VRA/DRA processing right here */
515}
516
517static int
518atiixp_chan_setspeed(kobj_t obj, void *data, uint32_t spd)
519{
520 /* XXX We're supposed to do VRA/DRA processing right here */
501 return ATI_IXP_BASE_RATE;
521 return (ATI_IXP_BASE_RATE);
502}
503
504static int
505atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
506{
507 struct atiixp_chinfo *ch = data;
508 struct atiixp_info *sc = ch->parent;
509
522}
523
524static int
525atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
526{
527 struct atiixp_chinfo *ch = data;
528 struct atiixp_info *sc = ch->parent;
529
510 if (blksz > (sc->bufsz / ch->dma_segs))
511 blksz = sc->bufsz / ch->dma_segs;
530 /* XXX Force static blocksize */
531 sndbuf_resize(ch->buffer, ch->dma_segs, ch->dma_blksz);
512
532
513 sndbuf_resize(ch->buffer, ch->dma_segs, blksz);
533 if (ch->dma_blksz != sndbuf_getblksz(ch->buffer)) {
534 device_printf(sc->dev,
535 "%s: WARNING - dma_blksz=%u != blksz=%u !!!\n",
536 __func__, ch->dma_blksz, sndbuf_getblksz(ch->buffer));
537 ch->dma_blksz = sndbuf_getblksz(ch->buffer);
538 }
514
539
515 return sndbuf_getblksz(ch->buffer);
540 return (ch->dma_blksz);
516}
517
518static void
519atiixp_buildsgdt(struct atiixp_chinfo *ch)
520{
541}
542
543static void
544atiixp_buildsgdt(struct atiixp_chinfo *ch)
545{
521 uint32_t addr, blksz;
546 uint32_t addr;
522 int i;
523
524 addr = sndbuf_getbufaddr(ch->buffer);
547 int i;
548
549 addr = sndbuf_getbufaddr(ch->buffer);
525 blksz = sndbuf_getblksz(ch->buffer);
526
527 for (i = 0; i < ch->dma_segs; i++) {
550
551 for (i = 0; i < ch->dma_segs; i++) {
528 ch->sgd_table[i].addr = htole32(addr + (i * blksz));
552 ch->sgd_table[i].addr = htole32(addr + (i * ch->dma_blksz));
529 ch->sgd_table[i].status = htole16(0);
553 ch->sgd_table[i].status = htole16(0);
530 ch->sgd_table[i].size = htole16(blksz >> 2);
531 ch->sgd_table[i].next = htole32((uint32_t)ch->sgd_addr +
554 ch->sgd_table[i].size = htole16(ch->dma_blksz >> 2);
555 ch->sgd_table[i].next = htole32((uint32_t)ch->sgd_addr +
532 (((i + 1) % ch->dma_segs) *
533 sizeof(struct atiixp_dma_op)));
534 }
556 (((i + 1) % ch->dma_segs) *
557 sizeof(struct atiixp_dma_op)));
558 }
559
560#ifdef ATI_IXP_DEBUG
561 ch->dma_ptr = 0;
562 ch->dma_prevptr = 0;
563#endif
535}
536
537static int
538atiixp_chan_trigger(kobj_t obj, void *data, int go)
539{
540 struct atiixp_chinfo *ch = data;
541 struct atiixp_info *sc = ch->parent;
542 uint32_t value;
543
544 atiixp_lock(sc);
545
546 switch (go) {
547 case PCMTRIG_START:
564}
565
566static int
567atiixp_chan_trigger(kobj_t obj, void *data, int go)
568{
569 struct atiixp_chinfo *ch = data;
570 struct atiixp_info *sc = ch->parent;
571 uint32_t value;
572
573 atiixp_lock(sc);
574
575 switch (go) {
576 case PCMTRIG_START:
548 atiixp_flush_dma(sc, ch);
577 atiixp_flush_dma(ch);
549 atiixp_buildsgdt(ch);
550 atiixp_wr(sc, ch->linkptr_bit, 0);
578 atiixp_buildsgdt(ch);
579 atiixp_wr(sc, ch->linkptr_bit, 0);
551 atiixp_enable_dma(sc, ch);
580 atiixp_enable_dma(ch);
552 atiixp_wr(sc, ch->linkptr_bit,
553 (uint32_t)ch->sgd_addr | ATI_REG_LINKPTR_EN);
554 break;
555 case PCMTRIG_STOP:
556 case PCMTRIG_ABORT:
581 atiixp_wr(sc, ch->linkptr_bit,
582 (uint32_t)ch->sgd_addr | ATI_REG_LINKPTR_EN);
583 break;
584 case PCMTRIG_STOP:
585 case PCMTRIG_ABORT:
557 atiixp_disable_dma(sc, ch);
558 atiixp_flush_dma(sc, ch);
586 atiixp_disable_dma(ch);
587 atiixp_flush_dma(ch);
559 break;
560 default:
561 atiixp_unlock(sc);
588 break;
589 default:
590 atiixp_unlock(sc);
562 return 0;
591 return (0);
563 break;
564 }
565
566 /* Update bus busy status */
567 value = atiixp_rd(sc, ATI_REG_IER);
568 if (atiixp_rd(sc, ATI_REG_CMD) & (
569 ATI_REG_CMD_SEND_EN | ATI_REG_CMD_RECEIVE_EN |
570 ATI_REG_CMD_SPDF_OUT_EN))
571 value |= ATI_REG_IER_SET_BUS_BUSY;
572 else
573 value &= ~ATI_REG_IER_SET_BUS_BUSY;
574 atiixp_wr(sc, ATI_REG_IER, value);
575
576 atiixp_unlock(sc);
577
592 break;
593 }
594
595 /* Update bus busy status */
596 value = atiixp_rd(sc, ATI_REG_IER);
597 if (atiixp_rd(sc, ATI_REG_CMD) & (
598 ATI_REG_CMD_SEND_EN | ATI_REG_CMD_RECEIVE_EN |
599 ATI_REG_CMD_SPDF_OUT_EN))
600 value |= ATI_REG_IER_SET_BUS_BUSY;
601 else
602 value &= ~ATI_REG_IER_SET_BUS_BUSY;
603 atiixp_wr(sc, ATI_REG_IER, value);
604
605 atiixp_unlock(sc);
606
578 return 0;
607 return (0);
579}
580
608}
609
581static int
582atiixp_chan_getptr(kobj_t obj, void *data)
610static __inline uint32_t
611atiixp_dmapos(struct atiixp_chinfo *ch)
583{
612{
584 struct atiixp_chinfo *ch = data;
585 struct atiixp_info *sc = ch->parent;
613 struct atiixp_info *sc = ch->parent;
586 uint32_t addr, align, retry, sz;
614 uint32_t reg, addr, sz, retry;
587 volatile uint32_t ptr;
588
615 volatile uint32_t ptr;
616
617 reg = ch->dma_dt_cur_bit;
589 addr = sndbuf_getbufaddr(ch->buffer);
618 addr = sndbuf_getbufaddr(ch->buffer);
590 align = (ch->fmt & AFMT_32BIT) ? 7 : 3;
591 retry = 100;
592 sz = sndbuf_getblksz(ch->buffer) * ch->dma_segs;
619 sz = ch->dma_segs * ch->dma_blksz;
620 retry = ATI_IXP_DMA_RETRY_MAX;
593
621
594 atiixp_lock(sc);
595 do {
622 do {
596 ptr = atiixp_rd(sc, ch->dma_dt_cur_bit);
623 ptr = atiixp_rd(sc, reg);
597 if (ptr < addr)
598 continue;
599 ptr -= addr;
624 if (ptr < addr)
625 continue;
626 ptr -= addr;
600 if (ptr < sz && !(ptr & align))
601 break;
602 } while (--retry);
603 atiixp_unlock(sc);
627 if (ptr < sz) {
628#ifdef ATI_IXP_DEBUG
629 if ((ptr & ~(ch->dma_blksz - 1)) != ch->dma_ptr) {
630 uint32_t delta;
604
631
605#if 0
606 if (retry != 100) {
607 device_printf(sc->dev,
608 "%saligned hwptr: dir=PCMDIR_%s ptr=%u fmt=0x%08x retry=%d\n",
609 (ptr & align) ? "un" : "",
610 (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", ptr,
611 ch->fmt, 100 - retry);
612 }
632 delta = (sz + ptr - ch->dma_prevptr) % sz;
633#ifndef ATI_IXP_DEBUG_VERBOSE
634 if (delta < ch->dma_blksz)
613#endif
635#endif
636 device_printf(sc->dev,
637 "PCMDIR_%s: incoherent DMA "
638 "dma_prevptr=%u ptr=%u "
639 "dma_ptr=%u dma_segs=%u "
640 "[delta=%u != dma_blksz=%u] "
641 "(%s)\n",
642 (ch->dir == PCMDIR_PLAY) ?
643 "PLAY" : "REC",
644 ch->dma_prevptr, ptr,
645 ch->dma_ptr, ch->dma_segs,
646 delta, ch->dma_blksz,
647 (delta < ch->dma_blksz) ?
648 "OVERLAPPED!" : "Ok");
649 ch->dma_ptr = ptr & ~(ch->dma_blksz - 1);
650 }
651 ch->dma_prevptr = ptr;
652#endif
653 return (ptr);
654 }
655 } while (--retry);
614
656
615 return (retry > 0) ? ptr : 0;
657 device_printf(sc->dev, "PCMDIR_%s: invalid DMA pointer ptr=%u\n",
658 (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", ptr);
659
660 return (0);
616}
617
661}
662
663static int
664atiixp_chan_getptr(kobj_t obj, void *data)
665{
666 struct atiixp_chinfo *ch = data;
667 struct atiixp_info *sc = ch->parent;
668 uint32_t ptr;
669
670 atiixp_lock(sc);
671 ptr = atiixp_dmapos(ch);
672 atiixp_unlock(sc);
673
674 return (ptr);
675}
676
618static struct pcmchan_caps *
619atiixp_chan_getcaps(kobj_t obj, void *data)
620{
621 struct atiixp_chinfo *ch = data;
622
623 if (ch->caps_32bit)
677static struct pcmchan_caps *
678atiixp_chan_getcaps(kobj_t obj, void *data)
679{
680 struct atiixp_chinfo *ch = data;
681
682 if (ch->caps_32bit)
624 return &atiixp_caps_32bit;
625 return &atiixp_caps;
683 return (&atiixp_caps_32bit);
684 return (&atiixp_caps);
626}
627
628static kobj_method_t atiixp_chan_methods[] = {
629 KOBJMETHOD(channel_init, atiixp_chan_init),
630 KOBJMETHOD(channel_setformat, atiixp_chan_setformat),
631 KOBJMETHOD(channel_setspeed, atiixp_chan_setspeed),
632 KOBJMETHOD(channel_setblocksize, atiixp_chan_setblocksize),
633 KOBJMETHOD(channel_trigger, atiixp_chan_trigger),

--- 5 unchanged lines hidden (view full) ---

639
640/*
641 * PCI driver interface
642 */
643static void
644atiixp_intr(void *p)
645{
646 struct atiixp_info *sc = p;
685}
686
687static kobj_method_t atiixp_chan_methods[] = {
688 KOBJMETHOD(channel_init, atiixp_chan_init),
689 KOBJMETHOD(channel_setformat, atiixp_chan_setformat),
690 KOBJMETHOD(channel_setspeed, atiixp_chan_setspeed),
691 KOBJMETHOD(channel_setblocksize, atiixp_chan_setblocksize),
692 KOBJMETHOD(channel_trigger, atiixp_chan_trigger),

--- 5 unchanged lines hidden (view full) ---

698
699/*
700 * PCI driver interface
701 */
702static void
703atiixp_intr(void *p)
704{
705 struct atiixp_info *sc = p;
706 struct atiixp_chinfo *ch;
647 uint32_t status, enable, detected_codecs;
648
649 atiixp_lock(sc);
650 status = atiixp_rd(sc, ATI_REG_ISR);
651
652 if (status == 0) {
653 atiixp_unlock(sc);
654 return;
655 }
656
657 if ((status & ATI_REG_ISR_IN_STATUS) && sc->rch.channel) {
707 uint32_t status, enable, detected_codecs;
708
709 atiixp_lock(sc);
710 status = atiixp_rd(sc, ATI_REG_ISR);
711
712 if (status == 0) {
713 atiixp_unlock(sc);
714 return;
715 }
716
717 if ((status & ATI_REG_ISR_IN_STATUS) && sc->rch.channel) {
718 ch = &sc->rch;
719#ifdef ATI_IXP_DEBUG
720 ch->dma_ptr = (ch->dma_ptr + ch->dma_blksz) %
721 (ch->dma_segs * ch->dma_blksz);
722#endif
658 atiixp_unlock(sc);
723 atiixp_unlock(sc);
659 chn_intr(sc->rch.channel);
724 chn_intr(ch->channel);
660 atiixp_lock(sc);
661 }
662 if ((status & ATI_REG_ISR_OUT_STATUS) && sc->pch.channel) {
725 atiixp_lock(sc);
726 }
727 if ((status & ATI_REG_ISR_OUT_STATUS) && sc->pch.channel) {
728 ch = &sc->pch;
729#ifdef ATI_IXP_DEBUG
730 ch->dma_ptr = (ch->dma_ptr + ch->dma_blksz) %
731 (ch->dma_segs * ch->dma_blksz);
732#endif
663 atiixp_unlock(sc);
733 atiixp_unlock(sc);
664 chn_intr(sc->pch.channel);
734 chn_intr(ch->channel);
665 atiixp_lock(sc);
666 }
667
668#if 0
669 if (status & ATI_REG_ISR_IN_XRUN) {
670 device_printf(sc->dev,
671 "Recieve IN XRUN interrupt\n");
672 }

--- 65 unchanged lines hidden (view full) ---

738
739 if (sc->delayed_attach.ich_func) {
740 config_intrhook_disestablish(&sc->delayed_attach);
741 sc->delayed_attach.ich_func = NULL;
742 }
743
744 /* wait for the interrupts to happen */
745 timeout = 100;
735 atiixp_lock(sc);
736 }
737
738#if 0
739 if (status & ATI_REG_ISR_IN_XRUN) {
740 device_printf(sc->dev,
741 "Recieve IN XRUN interrupt\n");
742 }

--- 65 unchanged lines hidden (view full) ---

808
809 if (sc->delayed_attach.ich_func) {
810 config_intrhook_disestablish(&sc->delayed_attach);
811 sc->delayed_attach.ich_func = NULL;
812 }
813
814 /* wait for the interrupts to happen */
815 timeout = 100;
746 while (--timeout) {
816 do {
747 msleep(sc, sc->lock, PWAIT, "ixpslp", 1);
748 if (sc->codec_not_ready_bits)
749 break;
817 msleep(sc, sc->lock, PWAIT, "ixpslp", 1);
818 if (sc->codec_not_ready_bits)
819 break;
750 }
820 } while (--timeout);
751
752 atiixp_disable_interrupts(sc);
753
754 if (timeout == 0) {
755 device_printf(sc->dev,
756 "WARNING: timeout during codec detection; "
757 "codecs might be present but haven't interrupted\n");
758 atiixp_unlock(sc);

--- 50 unchanged lines hidden (view full) ---

809 if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN))
810 goto postinitbad;
811
812 for (i = 0; i < ATI_IXP_NPCHAN; i++)
813 pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
814 for (i = 0; i < ATI_IXP_NRCHAN; i++)
815 pcm_addchan(sc->dev, PCMDIR_REC, &atiixp_chan_class, sc);
816
821
822 atiixp_disable_interrupts(sc);
823
824 if (timeout == 0) {
825 device_printf(sc->dev,
826 "WARNING: timeout during codec detection; "
827 "codecs might be present but haven't interrupted\n");
828 atiixp_unlock(sc);

--- 50 unchanged lines hidden (view full) ---

879 if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN))
880 goto postinitbad;
881
882 for (i = 0; i < ATI_IXP_NPCHAN; i++)
883 pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
884 for (i = 0; i < ATI_IXP_NRCHAN; i++)
885 pcm_addchan(sc->dev, PCMDIR_REC, &atiixp_chan_class, sc);
886
817 snprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s",
887 snprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s",
818 rman_get_start(sc->reg), rman_get_start(sc->irq),
819 PCM_KLDSTRING(snd_atiixp));
820
821 pcm_setstatus(sc->dev, status);
822
823 atiixp_lock(sc);
824 atiixp_enable_interrupts(sc);
825 atiixp_unlock(sc);

--- 46 unchanged lines hidden (view full) ---

872static int
873atiixp_pci_probe(device_t dev)
874{
875 int i;
876 uint16_t devid, vendor;
877
878 vendor = pci_get_vendor(dev);
879 devid = pci_get_device(dev);
888 rman_get_start(sc->reg), rman_get_start(sc->irq),
889 PCM_KLDSTRING(snd_atiixp));
890
891 pcm_setstatus(sc->dev, status);
892
893 atiixp_lock(sc);
894 atiixp_enable_interrupts(sc);
895 atiixp_unlock(sc);

--- 46 unchanged lines hidden (view full) ---

942static int
943atiixp_pci_probe(device_t dev)
944{
945 int i;
946 uint16_t devid, vendor;
947
948 vendor = pci_get_vendor(dev);
949 devid = pci_get_device(dev);
880 for (i = 0; i < sizeof(atiixp_hw)/sizeof(atiixp_hw[0]); i++) {
950 for (i = 0; i < sizeof(atiixp_hw) / sizeof(atiixp_hw[0]); i++) {
881 if (vendor == atiixp_hw[i].vendor &&
882 devid == atiixp_hw[i].devid) {
883 device_set_desc(dev, atiixp_hw[i].desc);
951 if (vendor == atiixp_hw[i].vendor &&
952 devid == atiixp_hw[i].devid) {
953 device_set_desc(dev, atiixp_hw[i].desc);
884 return BUS_PROBE_DEFAULT;
954 return (BUS_PROBE_DEFAULT);
885 }
886 }
887
955 }
956 }
957
888 return ENXIO;
958 return (ENXIO);
889}
890
891static int
892atiixp_pci_attach(device_t dev)
893{
894 struct atiixp_info *sc;
895 int i;
896
897 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
898 device_printf(dev, "cannot allocate softc\n");
959}
960
961static int
962atiixp_pci_attach(device_t dev)
963{
964 struct atiixp_info *sc;
965 int i;
966
967 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
968 device_printf(dev, "cannot allocate softc\n");
899 return ENXIO;
969 return (ENXIO);
900 }
901
902 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
903 sc->dev = dev;
904 /*
905 * Default DMA segments per playback / recording channel
906 */
970 }
971
972 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
973 sc->dev = dev;
974 /*
975 * Default DMA segments per playback / recording channel
976 */
907 sc->dma_segs = ATI_IXP_DMA_CHSEGS;
977 sc->dma_segs = ATI_IXP_DMA_CHSEGS_DEFAULT;
908
909 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
910 pci_enable_busmaster(dev);
911
912 sc->regid = PCIR_BAR(0);
913 sc->regtype = SYS_RES_MEMORY;
914 sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid,
915 RF_ACTIVE);
916
917 if (!sc->reg) {
918 device_printf(dev, "unable to allocate register space\n");
919 goto bad;
920 }
921
922 sc->st = rman_get_bustag(sc->reg);
923 sc->sh = rman_get_bushandle(sc->reg);
924
978
979 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
980 pci_enable_busmaster(dev);
981
982 sc->regid = PCIR_BAR(0);
983 sc->regtype = SYS_RES_MEMORY;
984 sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid,
985 RF_ACTIVE);
986
987 if (!sc->reg) {
988 device_printf(dev, "unable to allocate register space\n");
989 goto bad;
990 }
991
992 sc->st = rman_get_bustag(sc->reg);
993 sc->sh = rman_get_bushandle(sc->reg);
994
925 sc->bufsz = pcm_getbuffersize(dev, 4096, ATI_IXP_DEFAULT_BUFSZ, 65536);
995 sc->bufsz = pcm_getbuffersize(dev, ATI_IXP_BUFSZ_MIN,
996 ATI_IXP_BUFSZ_DEFAULT, ATI_IXP_BUFSZ_MAX);
926
927 sc->irqid = 0;
928 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
929 RF_ACTIVE | RF_SHAREABLE);
997
998 sc->irqid = 0;
999 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
1000 RF_ACTIVE | RF_SHAREABLE);
930 if (!sc->irq ||
1001 if (!sc->irq ||
931 snd_setup_intr(dev, sc->irq, INTR_MPSAFE,
932 atiixp_intr, sc, &sc->ih)) {
933 device_printf(dev, "unable to map interrupt\n");
934 goto bad;
935 }
936
937 /*
938 * Let the user choose the best DMA segments.

--- 18 unchanged lines hidden (view full) ---

957 if (sc->dma_segs < ATI_IXP_DMA_CHSEGS_MIN)
958 sc->dma_segs = ATI_IXP_DMA_CHSEGS_MIN;
959 else if (sc->dma_segs > ATI_IXP_DMA_CHSEGS_MAX)
960 sc->dma_segs = ATI_IXP_DMA_CHSEGS_MAX;
961
962 /*
963 * DMA tag for scatter-gather buffers and link pointers
964 */
1002 snd_setup_intr(dev, sc->irq, INTR_MPSAFE,
1003 atiixp_intr, sc, &sc->ih)) {
1004 device_printf(dev, "unable to map interrupt\n");
1005 goto bad;
1006 }
1007
1008 /*
1009 * Let the user choose the best DMA segments.

--- 18 unchanged lines hidden (view full) ---

1028 if (sc->dma_segs < ATI_IXP_DMA_CHSEGS_MIN)
1029 sc->dma_segs = ATI_IXP_DMA_CHSEGS_MIN;
1030 else if (sc->dma_segs > ATI_IXP_DMA_CHSEGS_MAX)
1031 sc->dma_segs = ATI_IXP_DMA_CHSEGS_MAX;
1032
1033 /*
1034 * DMA tag for scatter-gather buffers and link pointers
1035 */
965 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/sc->bufsz, /*boundary*/0,
1036 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
966 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
967 /*highaddr*/BUS_SPACE_MAXADDR,
968 /*filter*/NULL, /*filterarg*/NULL,
969 /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
970 /*flags*/0, /*lockfunc*/NULL,
971 /*lockarg*/NULL, &sc->parent_dmat) != 0) {
972 device_printf(dev, "unable to create dma tag\n");
973 goto bad;

--- 7 unchanged lines hidden (view full) ---

981 sizeof(struct atiixp_dma_op),
982 /*nsegments*/1, /*maxsegz*/0x3ffff,
983 /*flags*/0, /*lockfunc*/NULL,
984 /*lockarg*/NULL, &sc->sgd_dmat) != 0) {
985 device_printf(dev, "unable to create dma tag\n");
986 goto bad;
987 }
988
1037 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
1038 /*highaddr*/BUS_SPACE_MAXADDR,
1039 /*filter*/NULL, /*filterarg*/NULL,
1040 /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
1041 /*flags*/0, /*lockfunc*/NULL,
1042 /*lockarg*/NULL, &sc->parent_dmat) != 0) {
1043 device_printf(dev, "unable to create dma tag\n");
1044 goto bad;

--- 7 unchanged lines hidden (view full) ---

1052 sizeof(struct atiixp_dma_op),
1053 /*nsegments*/1, /*maxsegz*/0x3ffff,
1054 /*flags*/0, /*lockfunc*/NULL,
1055 /*lockarg*/NULL, &sc->sgd_dmat) != 0) {
1056 device_printf(dev, "unable to create dma tag\n");
1057 goto bad;
1058 }
1059
989 if (bus_dmamem_alloc(sc->sgd_dmat, (void **)&sc->sgd_table,
1060 if (bus_dmamem_alloc(sc->sgd_dmat, (void **)&sc->sgd_table,
990 BUS_DMA_NOWAIT, &sc->sgd_dmamap) == -1)
991 goto bad;
992
1061 BUS_DMA_NOWAIT, &sc->sgd_dmamap) == -1)
1062 goto bad;
1063
993 if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table,
1064 if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table,
994 sc->dma_segs * ATI_IXP_NCHANS *
995 sizeof(struct atiixp_dma_op),
996 atiixp_dma_cb, sc, 0))
997 goto bad;
998
999
1000 atiixp_chip_pre_init(sc);
1001
1002 sc->delayed_attach.ich_func = atiixp_chip_post_init;
1003 sc->delayed_attach.ich_arg = sc;
1004 if (cold == 0 ||
1005 config_intrhook_establish(&sc->delayed_attach) != 0) {
1006 sc->delayed_attach.ich_func = NULL;
1007 atiixp_chip_post_init(sc);
1008 }
1009
1065 sc->dma_segs * ATI_IXP_NCHANS *
1066 sizeof(struct atiixp_dma_op),
1067 atiixp_dma_cb, sc, 0))
1068 goto bad;
1069
1070
1071 atiixp_chip_pre_init(sc);
1072
1073 sc->delayed_attach.ich_func = atiixp_chip_post_init;
1074 sc->delayed_attach.ich_arg = sc;
1075 if (cold == 0 ||
1076 config_intrhook_establish(&sc->delayed_attach) != 0) {
1077 sc->delayed_attach.ich_func = NULL;
1078 atiixp_chip_post_init(sc);
1079 }
1080
1010 return 0;
1081 return (0);
1011
1012bad:
1013 atiixp_release_resource(sc);
1082
1083bad:
1084 atiixp_release_resource(sc);
1014 return ENXIO;
1085 return (ENXIO);
1015}
1016
1017static int
1018atiixp_pci_detach(device_t dev)
1019{
1020 int r;
1021 struct atiixp_info *sc;
1022
1023 sc = pcm_getdevinfo(dev);
1024 if (sc != NULL) {
1025 if (sc->codec != NULL) {
1026 r = pcm_unregister(dev);
1027 if (r)
1086}
1087
1088static int
1089atiixp_pci_detach(device_t dev)
1090{
1091 int r;
1092 struct atiixp_info *sc;
1093
1094 sc = pcm_getdevinfo(dev);
1095 if (sc != NULL) {
1096 if (sc->codec != NULL) {
1097 r = pcm_unregister(dev);
1098 if (r)
1028 return r;
1099 return (r);
1029 }
1030 sc->codec = NULL;
1100 }
1101 sc->codec = NULL;
1031 atiixp_disable_interrupts(sc);
1102 if (sc->st != 0 && sc->sh != 0)
1103 atiixp_disable_interrupts(sc);
1032 atiixp_release_resource(sc);
1033 free(sc, M_DEVBUF);
1034 }
1104 atiixp_release_resource(sc);
1105 free(sc, M_DEVBUF);
1106 }
1035 return 0;
1107 return (0);
1036}
1037
1038static int
1039atiixp_pci_suspend(device_t dev)
1040{
1041 struct atiixp_info *sc = pcm_getdevinfo(dev);
1042 uint32_t value;
1043

--- 14 unchanged lines hidden (view full) ---

1058 /* power down aclink and pci bus */
1059 atiixp_lock(sc);
1060 value = atiixp_rd(sc, ATI_REG_CMD);
1061 value |= ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET;
1062 atiixp_wr(sc, ATI_REG_CMD, ATI_REG_CMD_POWERDOWN);
1063 pci_set_powerstate(dev, PCI_POWERSTATE_D3);
1064 atiixp_unlock(sc);
1065
1108}
1109
1110static int
1111atiixp_pci_suspend(device_t dev)
1112{
1113 struct atiixp_info *sc = pcm_getdevinfo(dev);
1114 uint32_t value;
1115

--- 14 unchanged lines hidden (view full) ---

1130 /* power down aclink and pci bus */
1131 atiixp_lock(sc);
1132 value = atiixp_rd(sc, ATI_REG_CMD);
1133 value |= ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET;
1134 atiixp_wr(sc, ATI_REG_CMD, ATI_REG_CMD_POWERDOWN);
1135 pci_set_powerstate(dev, PCI_POWERSTATE_D3);
1136 atiixp_unlock(sc);
1137
1066 return 0;
1138 return (0);
1067}
1068
1069static int
1070atiixp_pci_resume(device_t dev)
1071{
1072 struct atiixp_info *sc = pcm_getdevinfo(dev);
1073
1074 atiixp_lock(sc);
1075 /* power up pci bus */
1076 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
1077 pci_enable_io(dev, SYS_RES_MEMORY);
1078 pci_enable_busmaster(dev);
1079 /* reset / power up aclink */
1080 atiixp_reset_aclink(sc);
1081 atiixp_unlock(sc);
1082
1083 if (mixer_reinit(dev) == -1) {
1084 device_printf(dev, "unable to reinitialize the mixer\n");
1139}
1140
1141static int
1142atiixp_pci_resume(device_t dev)
1143{
1144 struct atiixp_info *sc = pcm_getdevinfo(dev);
1145
1146 atiixp_lock(sc);
1147 /* power up pci bus */
1148 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
1149 pci_enable_io(dev, SYS_RES_MEMORY);
1150 pci_enable_busmaster(dev);
1151 /* reset / power up aclink */
1152 atiixp_reset_aclink(sc);
1153 atiixp_unlock(sc);
1154
1155 if (mixer_reinit(dev) == -1) {
1156 device_printf(dev, "unable to reinitialize the mixer\n");
1085 return ENXIO;
1157 return (ENXIO);
1086 }
1087
1088 /*
1089 * Resume channel activities. Reset channel format regardless
1090 * of its previous state.
1091 */
1092 if (sc->pch.channel) {
1093 if (sc->pch.fmt)

--- 8 unchanged lines hidden (view full) ---

1102 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START);
1103 }
1104
1105 /* enable interrupts */
1106 atiixp_lock(sc);
1107 atiixp_enable_interrupts(sc);
1108 atiixp_unlock(sc);
1109
1158 }
1159
1160 /*
1161 * Resume channel activities. Reset channel format regardless
1162 * of its previous state.
1163 */
1164 if (sc->pch.channel) {
1165 if (sc->pch.fmt)

--- 8 unchanged lines hidden (view full) ---

1174 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START);
1175 }
1176
1177 /* enable interrupts */
1178 atiixp_lock(sc);
1179 atiixp_enable_interrupts(sc);
1180 atiixp_unlock(sc);
1181
1110 return 0;
1182 return (0);
1111}
1112
1113static device_method_t atiixp_methods[] = {
1114 DEVMETHOD(device_probe, atiixp_pci_probe),
1115 DEVMETHOD(device_attach, atiixp_pci_attach),
1116 DEVMETHOD(device_detach, atiixp_pci_detach),
1117 DEVMETHOD(device_suspend, atiixp_pci_suspend),
1118 DEVMETHOD(device_resume, atiixp_pci_resume),

--- 12 unchanged lines hidden ---
1183}
1184
1185static device_method_t atiixp_methods[] = {
1186 DEVMETHOD(device_probe, atiixp_pci_probe),
1187 DEVMETHOD(device_attach, atiixp_pci_attach),
1188 DEVMETHOD(device_detach, atiixp_pci_detach),
1189 DEVMETHOD(device_suspend, atiixp_pci_suspend),
1190 DEVMETHOD(device_resume, atiixp_pci_resume),

--- 12 unchanged lines hidden ---