1 /* $NetBSD: elan520.c,v 1.45 2010/01/08 00:09:44 dyoung Exp $ */
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Device driver for the AMD Elan SC520 System Controller. This attaches
34 * where the "pchb" driver might normally attach, and provides support for
35 * extra features on the SC520, such as the watchdog timer and GPIO.
37 * Information about the GP bus echo bug work-around is from code posted
38 * to the "soekris-tech" mailing list by Jasper Wallace.
41 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: elan520.c,v 1.45 2010/01/08 00:09:44 dyoung Exp $");
45 #include <sys/param.h>
46 #include <sys/systm.h>
48 #include <sys/device.h>
50 #include <sys/mutex.h>
52 #include <sys/reboot.h>
54 #include <uvm/uvm_extern.h>
56 #include <machine/bus.h>
60 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcidevs.h>
66 #include <dev/gpio/gpiovar.h>
69 #include <arch/i386/pci/elan520reg.h>
71 #include <dev/sysmon/sysmonvar.h>
74 #define PG0_PROT_SIZE PAGE_SIZE
83 pci_chipset_tag_t sc_pc
;
85 bus_dma_tag_t sc_dmat
;
86 bus_dma_tag_t sc_dmat64
;
87 bus_space_tag_t sc_iot
;
88 bus_space_tag_t sc_memt
;
89 bus_space_handle_t sc_memh
;
96 struct sysmon_wdog sc_smw
;
106 struct gpio_chipset_tag sc_gpio_gc
;
107 gpio_pin_t sc_gpio_pins
[ELANSC_PIO_NPINS
];
116 static bool elansc_attached
= false;
117 int elansc_wpvnmi
= 1;
118 int elansc_pcinmi
= 1;
119 int elansc_do_protect_pg0
= 1;
122 static int elansc_gpio_pin_read(void *, int);
123 static void elansc_gpio_pin_write(void *, int, int);
124 static void elansc_gpio_pin_ctl(void *, int, int);
127 static void elansc_print_par(device_t
, int, uint32_t);
129 static void elanpar_intr_establish(device_t
, struct elansc_softc
*);
130 static void elanpar_intr_disestablish(struct elansc_softc
*);
131 static bool elanpar_shutdown(device_t
, int);
133 static void elanpex_intr_establish(device_t
, struct elansc_softc
*);
134 static void elanpex_intr_disestablish(struct elansc_softc
*);
135 static bool elanpex_shutdown(device_t
, int);
136 static int elansc_rescan(device_t
, const char *, const int *);
138 static void elansc_protect(struct elansc_softc
*, int, paddr_t
, uint32_t);
139 static bool elansc_shutdown(device_t
, int);
141 static const uint32_t sfkb
= 64 * 1024, fkb
= 4 * 1024;
144 elansc_childdetached(device_t self
, device_t child
)
146 struct elansc_softc
*sc
= device_private(self
);
148 if (child
== sc
->sc_par
)
150 if (child
== sc
->sc_pex
)
152 if (child
== sc
->sc_pci
)
154 if (child
== sc
->sc_gpio
)
159 elansc_match(device_t parent
, cfdata_t match
, void *aux
)
161 struct pcibus_attach_args
*pba
= aux
;
168 if (pcimatch(parent
, match
, aux
) == 0)
171 if (pba
->pba_bus
!= 0)
174 tag
= pci_make_tag(pba
->pba_pc
, 0, 0, 0);
175 id
= pci_conf_read(pba
->pba_pc
, tag
, PCI_ID_REG
);
177 if (PCI_VENDOR(id
) == PCI_VENDOR_AMD
&&
178 PCI_PRODUCT(id
) == PCI_PRODUCT_AMD_SC520_SC
)
185 * Performance tuning for Soekris net4501:
186 * - enable SDRAM write buffer and read prefetching
191 dbctl
= bus_space_read_1(memt
, memh
, MMCR_DBCTL
);
192 dbctl
&= ~MMCR_DBCTL_WB_WM_MASK
;
193 dbctl
|= MMCR_DBCTL_WB_WM_16DW
;
194 dbctl
|= MMCR_DBCTL_WB_ENB
| MMCR_DBCTL_RAB_ENB
;
195 bus_space_write_1(memt
, memh
, MMCR_DBCTL
, dbctl
);
199 * Performance tuning for PCI bus on the AMD Elan SC520:
200 * - enable concurrent arbitration of PCI and CPU busses
202 * - enable PCI automatic delayed read transactions and
204 * - enable PCI read buffer snooping (coherency)
207 elansc_perf_tune(device_t self
, bus_space_tag_t memt
, bus_space_handle_t memh
)
211 const bool concurrency
= true; /* concurrent bus arbitration */
213 sysarbctl
= bus_space_read_1(memt
, memh
, MMCR_SYSARBCTL
);
214 if ((sysarbctl
& MMCR_SYSARBCTL_CNCR_MODE_ENB
) != 0) {
215 aprint_debug_dev(self
,
216 "concurrent arbitration mode is active\n");
217 } else if (concurrency
) {
218 aprint_verbose_dev(self
, "activating concurrent "
219 "arbitration mode\n");
220 /* activate concurrent bus arbitration */
221 sysarbctl
|= MMCR_SYSARBCTL_CNCR_MODE_ENB
;
222 bus_space_write_1(memt
, memh
, MMCR_SYSARBCTL
, sysarbctl
);
225 hbctl
= bus_space_read_2(memt
, memh
, MMCR_HBCTL
);
227 /* target read FIFO snoop */
228 if ((hbctl
& MMCR_HBCTL_T_PURGE_RD_ENB
) != 0)
229 aprint_debug_dev(self
, "read-FIFO snooping is active\n");
231 aprint_verbose_dev(self
, "activating read-FIFO snooping\n");
232 hbctl
|= MMCR_HBCTL_T_PURGE_RD_ENB
;
235 if ((hbctl
& MMCR_HBCTL_M_WPOST_ENB
) != 0)
236 aprint_debug_dev(self
, "CPU->PCI write-posting is active\n");
237 else if (concurrency
) {
238 aprint_verbose_dev(self
, "activating CPU->PCI write-posting\n");
239 hbctl
|= MMCR_HBCTL_M_WPOST_ENB
;
242 /* auto delay read txn: looks safe, but seems to cause
243 * net4526 w/ minipci ath fits
246 if ((hbctl
& MMCR_HBCTL_T_DLYTR_ENB_AUTORETRY
) != 0)
247 aprint_debug_dev(self
,
248 "automatic read transaction delay is active\n");
250 aprint_verbose_dev(self
,
251 "activating automatic read transaction delay\n");
252 hbctl
|= MMCR_HBCTL_T_DLYTR_ENB_AUTORETRY
;
255 bus_space_write_2(memt
, memh
, MMCR_HBCTL
, hbctl
);
259 elansc_wdogctl_write(struct elansc_softc
*sc
, uint16_t val
)
261 uint8_t echo_mode
= 0; /* XXX: gcc */
263 KASSERT(mutex_owned(&sc
->sc_mtx
));
265 /* Switch off GP bus echo mode if we need to. */
266 if (sc
->sc_echobug
) {
267 echo_mode
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
,
269 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
,
270 MMCR_GPECHO
, echo_mode
& ~GPECHO_GP_ECHO_ENB
);
273 /* Unlock the register. */
274 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WDTMRCTL
,
276 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WDTMRCTL
,
279 /* Write the value. */
280 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WDTMRCTL
, val
);
282 /* Switch GP bus echo mode back. */
284 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_GPECHO
,
289 elansc_wdogctl_reset(struct elansc_softc
*sc
)
291 uint8_t echo_mode
= 0/* XXX: gcc */;
293 KASSERT(mutex_owned(&sc
->sc_mtx
));
295 /* Switch off GP bus echo mode if we need to. */
296 if (sc
->sc_echobug
) {
297 echo_mode
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
,
299 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
,
300 MMCR_GPECHO
, echo_mode
& ~GPECHO_GP_ECHO_ENB
);
303 /* Reset the watchdog. */
304 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WDTMRCTL
,
306 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WDTMRCTL
,
309 /* Switch GP bus echo mode back. */
311 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_GPECHO
,
315 static const struct {
316 int period
; /* whole seconds */
317 uint16_t exp
; /* exponent select */
318 } elansc_wdog_periods
[] = {
319 { 1, WDTMRCTL_EXP_SEL25
},
320 { 2, WDTMRCTL_EXP_SEL26
},
321 { 4, WDTMRCTL_EXP_SEL27
},
322 { 8, WDTMRCTL_EXP_SEL28
},
323 { 16, WDTMRCTL_EXP_SEL29
},
324 { 32, WDTMRCTL_EXP_SEL30
},
329 elansc_wdog_arm(struct elansc_softc
*sc
)
331 struct sysmon_wdog
*smw
= &sc
->sc_smw
;
333 uint16_t exp_sel
= 0; /* XXX: gcc */
335 KASSERT(mutex_owned(&sc
->sc_mtx
));
337 if (smw
->smw_period
== WDOG_PERIOD_DEFAULT
) {
338 smw
->smw_period
= 32;
339 exp_sel
= WDTMRCTL_EXP_SEL30
;
341 for (i
= 0; elansc_wdog_periods
[i
].period
!= 0; i
++) {
342 if (elansc_wdog_periods
[i
].period
==
344 exp_sel
= elansc_wdog_periods
[i
].exp
;
348 if (elansc_wdog_periods
[i
].period
== 0)
351 elansc_wdogctl_write(sc
, WDTMRCTL_ENB
|
352 WDTMRCTL_WRST_ENB
| exp_sel
);
353 elansc_wdogctl_reset(sc
);
358 elansc_wdog_setmode(struct sysmon_wdog
*smw
)
360 struct elansc_softc
*sc
= smw
->smw_cookie
;
363 mutex_enter(&sc
->sc_mtx
);
365 if (!device_is_active(sc
->sc_dev
))
367 else if ((smw
->smw_mode
& WDOG_MODE_MASK
) == WDOG_MODE_DISARMED
) {
368 elansc_wdogctl_write(sc
,
369 WDTMRCTL_WRST_ENB
| WDTMRCTL_EXP_SEL30
);
371 rc
= elansc_wdog_arm(sc
);
373 mutex_exit(&sc
->sc_mtx
);
378 elansc_wdog_tickle(struct sysmon_wdog
*smw
)
380 struct elansc_softc
*sc
= smw
->smw_cookie
;
382 mutex_enter(&sc
->sc_mtx
);
383 elansc_wdogctl_reset(sc
);
384 mutex_exit(&sc
->sc_mtx
);
388 static const char *elansc_speeds
[] = {
396 elanpar_intr(void *arg
)
398 struct elansc_softc
*sc
= arg
;
404 wpvsta
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WPVSTA
);
406 if ((wpvsta
& MMCR_WPVSTA_WPV_STA
) == 0)
409 win
= __SHIFTOUT(wpvsta
, MMCR_WPVSTA_WPV_WINDOW
);
411 par
= bus_space_read_4(sc
->sc_memt
, sc
->sc_memh
, MMCR_PAR(win
));
413 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WPVSTA
,
414 MMCR_WPVSTA_WPV_STA
);
416 switch (wpvsta
& MMCR_WPVSTA_WPV_MSTR
) {
417 case MMCR_WPVSTA_WPV_MSTR_CPU
:
420 case MMCR_WPVSTA_WPV_MSTR_PCI
:
423 case MMCR_WPVSTA_WPV_MSTR_GP
:
430 printf_tolog("%s: %s violated write-protect window %u\n",
431 device_xname(sc
->sc_par
), wpvstr
, win
);
432 elansc_print_par(sc
->sc_par
, win
, par
);
437 elanpar_nmi(const struct trapframe
*tf
, void *arg
)
440 return elanpar_intr(arg
);
444 elanpex_intr(void *arg
)
450 [0] = {.string
= "not latched"}
451 , [1] = {.string
= "special cycle"}
452 , [2] = {.string
= "i/o read"}
453 , [3] = {.string
= "i/o write"}
454 , [4] = {.string
= "4"}
455 , [5] = {.string
= "5"}
456 , [6] = {.string
= "memory rd"}
457 , [7] = {.string
= "memory wr"}
458 , [8] = {.string
= "8"}
459 , [9] = {.string
= "9"}
460 , [10] = {.string
= "cfg rd", .nonfatal
= true}
461 , [11] = {.string
= "cfg wr"}
462 , [12] = {.string
= "memory rd mul"}
463 , [13] = {.string
= "dual-address cycle"}
464 , [14] = {.string
= "memory rd line"}
465 , [15] = {.string
= "memory wr & inv"}
468 static const struct {
472 {MMCR_HBMSTIRQSTA_M_RTRTO_IRQ_STA
, "retry timeout"}
473 , {MMCR_HBMSTIRQSTA_M_TABRT_IRQ_STA
, "target abort"}
474 , {MMCR_HBMSTIRQSTA_M_MABRT_IRQ_STA
, "abort"}
475 , {MMCR_HBMSTIRQSTA_M_SERR_IRQ_STA
, "system error"}
476 , {MMCR_HBMSTIRQSTA_M_RPER_IRQ_STA
, "received parity error"}
477 , {MMCR_HBMSTIRQSTA_M_DPER_IRQ_STA
, "detected parity error"}
479 {MMCR_HBTGTIRQSTA_T_DLYTO_IRQ_STA
, "delayed txn timeout"}
480 , {MMCR_HBTGTIRQSTA_T_APER_IRQ_STA
, "address parity"}
481 , {MMCR_HBTGTIRQSTA_T_DPER_IRQ_STA
, "data parity"}
484 uint16_t mstcmd
, mstirq
, tgtid
, tgtirq
;
486 uint16_t mstack
= 0, tgtack
= 0;
487 int fatal
= 0, i
, handled
= 0;
488 struct elansc_softc
*sc
= arg
;
490 pciarbsta
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_PCIARBSTA
);
491 mstirq
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBMSTIRQSTA
);
492 mstaddr
= bus_space_read_4(sc
->sc_memt
, sc
->sc_memh
, MMCR_MSTINTADD
);
493 tgtirq
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBTGTIRQSTA
);
495 if ((pciarbsta
& MMCR_PCIARBSTA_GNT_TO_STA
) != 0) {
497 "%s: grant time-out, GNT%" __PRIuBITS
"# asserted\n",
498 device_xname(sc
->sc_pex
),
499 __SHIFTOUT(pciarbsta
, MMCR_PCIARBSTA_GNT_TO_ID
));
500 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_PCIARBSTA
,
501 MMCR_PCIARBSTA_GNT_TO_STA
);
505 mstcmd
= __SHIFTOUT(mstirq
, MMCR_HBMSTIRQSTA_M_CMD_IRQ_ID
);
507 for (i
= 0; i
< __arraycount(mmsg
); i
++) {
508 if ((mstirq
& mmsg
[i
].bit
) == 0)
510 printf_tolog("%s: %s %08" PRIx32
" master %s\n",
511 device_xname(sc
->sc_pex
), cmd
[mstcmd
].string
, mstaddr
,
514 mstack
|= mmsg
[i
].bit
;
515 if (!cmd
[mstcmd
].nonfatal
)
519 tgtid
= __SHIFTOUT(tgtirq
, MMCR_HBTGTIRQSTA_T_IRQ_ID
);
521 for (i
= 0; i
< __arraycount(tmsg
); i
++) {
522 if ((tgtirq
& tmsg
[i
].bit
) == 0)
524 printf_tolog("%s: %1x target %s\n", device_xname(sc
->sc_pex
),
526 tgtack
|= tmsg
[i
].bit
;
529 /* acknowledge interrupts */
532 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBTGTIRQSTA
,
537 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBMSTIRQSTA
,
540 return fatal
? 0 : (handled
? 1 : 0);
544 elanpex_nmi(const struct trapframe
*tf
, void *arg
)
547 return elanpex_intr(arg
);
550 #define elansc_print_1(__dev, __sc, __reg) \
552 aprint_debug_dev(__dev, \
553 "%s: %s %02" PRIx8 "\n", __func__, #__reg, \
554 bus_space_read_1((__sc)->sc_memt, (__sc)->sc_memh, __reg)); \
555 } while (/*CONSTCOND*/0)
558 elansc_print_par(device_t dev
, int i
, uint32_t par
)
560 uint32_t addr
, sz
, unit
;
563 if ((boothowto
& AB_DEBUG
) == 0)
566 switch (par
& MMCR_PAR_TARGET
) {
568 case MMCR_PAR_TARGET_OFF
:
571 case MMCR_PAR_TARGET_GPIO
:
574 case MMCR_PAR_TARGET_GPMEM
:
577 case MMCR_PAR_TARGET_PCI
:
580 case MMCR_PAR_TARGET_BOOTCS
:
583 case MMCR_PAR_TARGET_ROMCS1
:
586 case MMCR_PAR_TARGET_ROMCS2
:
589 case MMCR_PAR_TARGET_SDRAM
:
593 if ((par
& MMCR_PAR_TARGET
) == MMCR_PAR_TARGET_GPIO
) {
595 sz
= __SHIFTOUT(par
, MMCR_PAR_IO_SZ
);
596 addr
= __SHIFTOUT(par
, MMCR_PAR_IO_ST_ADR
);
597 } else if ((par
& MMCR_PAR_PG_SZ
) != 0) {
599 sz
= __SHIFTOUT(par
, MMCR_PAR_64KB_SZ
);
600 addr
= __SHIFTOUT(par
, MMCR_PAR_64KB_ST_ADR
);
603 sz
= __SHIFTOUT(par
, MMCR_PAR_4KB_SZ
);
604 addr
= __SHIFTOUT(par
, MMCR_PAR_4KB_ST_ADR
);
608 "%s: PAR[%d] %08" PRIx32
" tgt %s attr %1" __PRIxBITS
609 " start %08" PRIx32
" size %" PRIu32
"\n", device_xname(dev
),
610 i
, par
, tgtstr
, __SHIFTOUT(par
, MMCR_PAR_ATTR
),
611 addr
* unit
, (sz
+ 1) * unit
);
615 elansc_print_all_par(device_t dev
,
616 bus_space_tag_t memt
, bus_space_handle_t memh
)
621 for (i
= 0; i
< 16; i
++) {
622 par
= bus_space_read_4(memt
, memh
, MMCR_PAR(i
));
623 elansc_print_par(dev
, i
, par
);
628 elansc_alloc_par(bus_space_tag_t memt
, bus_space_handle_t memh
)
633 for (i
= 0; i
< 16; i
++) {
635 par
= bus_space_read_4(memt
, memh
, MMCR_PAR(i
));
637 if ((par
& MMCR_PAR_TARGET
) == MMCR_PAR_TARGET_OFF
)
646 elansc_disable_par(bus_space_tag_t memt
, bus_space_handle_t memh
, int idx
)
649 par
= bus_space_read_4(memt
, memh
, MMCR_PAR(idx
));
650 par
&= ~MMCR_PAR_TARGET
;
651 par
|= MMCR_PAR_TARGET_OFF
;
652 bus_space_write_4(memt
, memh
, MMCR_PAR(idx
), par
);
656 region_paddr_to_par(struct pareg
*region0
, struct pareg
*regions
, uint32_t unit
)
658 struct pareg
*residue
= regions
;
660 paddr_t start0
, end0
;
662 start0
= region0
->start
;
665 if (start0
% unit
!= 0)
666 start
= start0
+ unit
- start0
% unit
;
670 end
= end0
- end0
% unit
;
675 residue
->start
= start
;
679 if (start0
< start
) {
680 residue
->start
= start0
;
681 residue
->end
= start
;
685 residue
->start
= end
;
689 return residue
- regions
;
693 elansc_protect_text(device_t self
, struct elansc_softc
*sc
)
695 int i
, j
, nregion
, pidx
, tidx
= 0, xnregion
;
697 uint32_t protsize
, unprotsize
;
698 paddr_t start_pa
, end_pa
;
699 extern char kernel_text
, etext
;
700 bus_space_tag_t memt
;
701 bus_space_handle_t memh
;
702 struct pareg region0
, regions
[3], xregions
[3];
704 sc
->sc_textpar
[0] = sc
->sc_textpar
[1] = sc
->sc_textpar
[2] = -1;
709 if (!pmap_extract(pmap_kernel(), (vaddr_t
)&kernel_text
,
711 !pmap_extract(pmap_kernel(), (vaddr_t
)&etext
,
715 if (&etext
- &kernel_text
!= region0
.end
- region0
.start
) {
716 aprint_error_dev(self
, "kernel text may not be contiguous\n");
720 if ((pidx
= elansc_alloc_par(memt
, memh
)) == -1) {
721 aprint_error_dev(self
, "cannot allocate PAR\n");
725 par
= bus_space_read_4(memt
, memh
, MMCR_PAR(pidx
));
727 aprint_debug_dev(self
,
728 "protect kernel text at physical addresses %p - %p\n",
729 (void *)region0
.start
, (void *)region0
.end
);
731 nregion
= region_paddr_to_par(®ion0
, regions
, sfkb
);
733 aprint_error_dev(self
, "kernel text is unprotected\n");
738 for (i
= 1; i
< nregion
; i
++)
739 unprotsize
+= regions
[i
].end
- regions
[i
].start
;
741 start_pa
= regions
[0].start
;
742 end_pa
= regions
[0].end
;
744 aprint_debug_dev(self
,
745 "actually protect kernel text at physical addresses %p - %p\n",
746 (void *)start_pa
, (void *)end_pa
);
748 aprint_verbose_dev(self
,
749 "%" PRIu32
" bytes of kernel text are unprotected\n", unprotsize
);
751 protsize
= end_pa
- start_pa
;
753 elansc_protect(sc
, pidx
, start_pa
, protsize
);
755 sc
->sc_textpar
[tidx
++] = pidx
;
758 for (i
= 1; i
< nregion
; i
++) {
759 xnregion
= region_paddr_to_par(®ions
[i
], xregions
, fkb
);
761 aprint_verbose_dev(self
, "skip region %p - %p\n",
762 (void *)regions
[i
].start
, (void *)regions
[i
].end
);
765 if ((pidx
= elansc_alloc_par(memt
, memh
)) == -1) {
766 unprotsize
+= regions
[i
].end
- regions
[i
].start
;
769 elansc_protect(sc
, pidx
, xregions
[0].start
,
770 xregions
[0].end
- xregions
[0].start
);
771 sc
->sc_textpar
[tidx
++] = pidx
;
773 aprint_debug_dev(self
,
774 "protect add'l kernel text at physical addresses %p - %p\n",
775 (void *)xregions
[0].start
, (void *)xregions
[0].end
);
777 for (j
= 1; j
< xnregion
; j
++)
778 unprotsize
+= xregions
[j
].end
- xregions
[j
].start
;
780 aprint_verbose_dev(self
,
781 "%" PRIu32
" bytes of kernel text still unprotected\n", unprotsize
);
786 elansc_protect(struct elansc_softc
*sc
, int pidx
, paddr_t addr
, uint32_t sz
)
788 uint32_t addr_field
, blksz
, par
, size_field
;
790 /* set attribute, target. */
791 par
= MMCR_PAR_TARGET_SDRAM
| MMCR_PAR_ATTR_NOWRITE
;
793 KASSERT(addr
% fkb
== 0 && sz
% fkb
== 0);
795 if (addr
% sfkb
== 0 && sz
% sfkb
== 0) {
796 par
|= MMCR_PAR_PG_SZ
;
798 size_field
= MMCR_PAR_64KB_SZ
;
799 addr_field
= MMCR_PAR_64KB_ST_ADR
;
802 size_field
= MMCR_PAR_4KB_SZ
;
803 addr_field
= MMCR_PAR_4KB_ST_ADR
;
807 KASSERT(sz
/ blksz
- 1 <= __SHIFTOUT_MASK(size_field
));
808 KASSERT(addr
/ blksz
<= __SHIFTOUT_MASK(addr_field
));
810 /* set size and address. */
811 par
|= __SHIFTIN(sz
/ blksz
- 1, size_field
);
812 par
|= __SHIFTIN(addr
/ blksz
, addr_field
);
814 bus_space_write_4(sc
->sc_memt
, sc
->sc_memh
, MMCR_PAR(pidx
), par
);
818 elansc_protect_pg0(device_t self
, struct elansc_softc
*sc
)
821 const paddr_t pg0_paddr
= 0;
822 bus_space_tag_t memt
;
823 bus_space_handle_t memh
;
828 if (elansc_do_protect_pg0
== 0)
831 if ((pidx
= elansc_alloc_par(memt
, memh
)) == -1)
834 aprint_debug_dev(self
, "protect page 0\n");
836 elansc_protect(sc
, pidx
, pg0_paddr
, PG0_PROT_SIZE
);
841 elanpex_intr_ack(bus_space_tag_t memt
, bus_space_handle_t memh
)
843 bus_space_write_1(memt
, memh
, MMCR_PCIARBSTA
,
844 MMCR_PCIARBSTA_GNT_TO_STA
);
845 bus_space_write_2(memt
, memh
, MMCR_HBTGTIRQSTA
, MMCR_TGTIRQ_ACT
);
846 bus_space_write_2(memt
, memh
, MMCR_HBMSTIRQSTA
, MMCR_MSTIRQ_ACT
);
850 elansc_suspend(device_t dev
, pmf_qual_t qual
)
853 struct elansc_softc
*sc
= device_private(dev
);
855 mutex_enter(&sc
->sc_mtx
);
856 rc
= ((sc
->sc_smw
.smw_mode
& WDOG_MODE_MASK
) == WDOG_MODE_DISARMED
);
857 mutex_exit(&sc
->sc_mtx
);
859 aprint_debug_dev(dev
, "watchdog enabled, suspend forbidden");
864 elansc_resume(device_t dev
, pmf_qual_t qual
)
866 struct elansc_softc
*sc
= device_private(dev
);
868 mutex_enter(&sc
->sc_mtx
);
869 /* Set up the watchdog registers with some defaults. */
870 elansc_wdogctl_write(sc
, WDTMRCTL_WRST_ENB
| WDTMRCTL_EXP_SEL30
);
872 /* ...and clear it. */
873 elansc_wdogctl_reset(sc
);
874 mutex_exit(&sc
->sc_mtx
);
876 elansc_perf_tune(dev
, sc
->sc_memt
, sc
->sc_memh
);
882 elansc_shutdown(device_t self
, int how
)
884 struct elansc_softc
*sc
= device_private(self
);
886 /* Set up the watchdog registers with some defaults. */
887 elansc_wdogctl_write(sc
, WDTMRCTL_WRST_ENB
| WDTMRCTL_EXP_SEL30
);
889 /* ...and clear it. */
890 elansc_wdogctl_reset(sc
);
896 elansc_detach(device_t self
, int flags
)
899 struct elansc_softc
*sc
= device_private(self
);
901 if ((rc
= config_detach_children(self
, flags
)) != 0)
904 pmf_device_deregister(self
);
906 if ((flags
& DETACH_SHUTDOWN
) == 0 &&
907 (rc
= sysmon_wdog_unregister(&sc
->sc_smw
)) != 0) {
913 mutex_enter(&sc
->sc_mtx
);
915 (void)elansc_shutdown(self
, 0);
917 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_PICICR
, sc
->sc_picicr
);
918 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_MPICMODE
,
921 mutex_exit(&sc
->sc_mtx
);
922 mutex_destroy(&sc
->sc_mtx
);
924 bus_space_unmap(sc
->sc_memt
, sc
->sc_memh
, PAGE_SIZE
);
925 elansc_attached
= false;
930 elansc_intr_establish(device_t dev
, int (*handler
)(void *), void *arg
)
935 if ((pic
= intr_findpic(ELAN_IRQ
)) == NULL
) {
936 aprint_error_dev(dev
, "PIC for irq %d not found\n",
939 } else if ((ih
= intr_establish(ELAN_IRQ
, pic
, ELAN_IRQ
,
940 IST_LEVEL
, IPL_HIGH
, handler
, arg
, false)) == NULL
) {
941 aprint_error_dev(dev
,
942 "could not establish interrupt\n");
945 aprint_verbose_dev(dev
, "interrupting at irq %d\n", ELAN_IRQ
);
950 elanpex_resume(device_t self
, pmf_qual_t qual
)
952 struct elansc_softc
*sc
= device_private(device_parent(self
));
954 elanpex_intr_establish(self
, sc
);
955 return sc
->sc_eih
!= NULL
;
959 elanpex_suspend(device_t self
, pmf_qual_t qual
)
961 struct elansc_softc
*sc
= device_private(device_parent(self
));
963 elanpex_intr_disestablish(sc
);
969 elanpar_resume(device_t self
, pmf_qual_t qual
)
971 struct elansc_softc
*sc
= device_private(device_parent(self
));
973 elanpar_intr_establish(self
, sc
);
974 return sc
->sc_pih
!= NULL
;
978 elanpar_suspend(device_t self
, pmf_qual_t qual
)
980 struct elansc_softc
*sc
= device_private(device_parent(self
));
982 elanpar_intr_disestablish(sc
);
988 elanpex_intr_establish(device_t self
, struct elansc_softc
*sc
)
991 uint16_t pcihostmap
, mstirq
, tgtirq
;
993 pcihostmap
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
,
995 /* Priority P2 (Master PIC IR1) */
996 pcihostmap
&= ~MMCR_PCIHOSTMAP_PCI_IRQ_MAP
;
997 pcihostmap
|= __SHIFTIN(__BIT(ELAN_IRQ
), MMCR_PCIHOSTMAP_PCI_IRQ_MAP
);
999 pcihostmap
|= MMCR_PCIHOSTMAP_PCI_NMI_ENB
;
1000 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_PCIHOSTMAP
,
1003 elanpex_intr_ack(sc
->sc_memt
, sc
->sc_memh
);
1005 sysarbctl
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_SYSARBCTL
);
1006 mstirq
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBMSTIRQCTL
);
1007 tgtirq
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBTGTIRQCTL
);
1009 sysarbctl
|= MMCR_SYSARBCTL_GNT_TO_INT_ENB
;
1011 mstirq
|= MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_ENB
;
1012 mstirq
|= MMCR_HBMSTIRQCTL_M_TABRT_IRQ_ENB
;
1013 mstirq
|= MMCR_HBMSTIRQCTL_M_MABRT_IRQ_ENB
;
1014 mstirq
|= MMCR_HBMSTIRQCTL_M_SERR_IRQ_ENB
;
1015 mstirq
|= MMCR_HBMSTIRQCTL_M_RPER_IRQ_ENB
;
1016 mstirq
|= MMCR_HBMSTIRQCTL_M_DPER_IRQ_ENB
;
1018 tgtirq
|= MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_ENB
;
1019 tgtirq
|= MMCR_HBTGTIRQCTL_T_APER_IRQ_ENB
;
1020 tgtirq
|= MMCR_HBTGTIRQCTL_T_DPER_IRQ_ENB
;
1022 if (elansc_pcinmi
) {
1023 sc
->sc_eih
= nmi_establish(elanpex_nmi
, sc
);
1025 /* Activate NMI instead of maskable interrupts for
1026 * all PCI exceptions:
1028 mstirq
|= MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_SEL
;
1029 mstirq
|= MMCR_HBMSTIRQCTL_M_TABRT_IRQ_SEL
;
1030 mstirq
|= MMCR_HBMSTIRQCTL_M_MABRT_IRQ_SEL
;
1031 mstirq
|= MMCR_HBMSTIRQCTL_M_SERR_IRQ_SEL
;
1032 mstirq
|= MMCR_HBMSTIRQCTL_M_RPER_IRQ_SEL
;
1033 mstirq
|= MMCR_HBMSTIRQCTL_M_DPER_IRQ_SEL
;
1035 tgtirq
|= MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_SEL
;
1036 tgtirq
|= MMCR_HBTGTIRQCTL_T_APER_IRQ_SEL
;
1037 tgtirq
|= MMCR_HBTGTIRQCTL_T_DPER_IRQ_SEL
;
1039 sc
->sc_eih
= elansc_intr_establish(self
, elanpex_intr
, sc
);
1041 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_SYSARBCTL
, sysarbctl
);
1042 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBMSTIRQCTL
, mstirq
);
1043 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBTGTIRQCTL
, tgtirq
);
1047 elanpex_attach(device_t parent
, device_t self
, void *aux
)
1049 struct elansc_softc
*sc
= device_private(parent
);
1051 aprint_naive(": PCI Exceptions\n");
1052 aprint_normal(": AMD Elan SC520 PCI Exceptions\n");
1054 elanpex_intr_establish(self
, sc
);
1056 aprint_debug_dev(self
, "HBMSTIRQCTL %04x\n",
1057 bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBMSTIRQCTL
));
1059 aprint_debug_dev(self
, "HBTGTIRQCTL %04x\n",
1060 bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBTGTIRQCTL
));
1062 aprint_debug_dev(self
, "PCIHOSTMAP %04x\n",
1063 bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_PCIHOSTMAP
));
1065 pci_conf_write(sc
->sc_pc
, sc
->sc_tag
, PCI_COMMAND_STATUS_REG
,
1066 pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, PCI_COMMAND_STATUS_REG
) |
1067 PCI_COMMAND_PARITY_ENABLE
|PCI_COMMAND_SERR_ENABLE
);
1069 if (!pmf_device_register1(self
, elanpex_suspend
, elanpex_resume
,
1071 aprint_error_dev(self
, "could not establish power hooks\n");
1075 elanpex_shutdown(device_t self
, int flags
)
1077 struct elansc_softc
*sc
= device_private(device_parent(self
));
1079 uint16_t pcihostmap
, mstirq
, tgtirq
;
1081 sysarbctl
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_SYSARBCTL
);
1082 sysarbctl
&= ~MMCR_SYSARBCTL_GNT_TO_INT_ENB
;
1083 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_SYSARBCTL
, sysarbctl
);
1085 mstirq
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBMSTIRQCTL
);
1086 mstirq
&= ~MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_ENB
;
1087 mstirq
&= ~MMCR_HBMSTIRQCTL_M_TABRT_IRQ_ENB
;
1088 mstirq
&= ~MMCR_HBMSTIRQCTL_M_MABRT_IRQ_ENB
;
1089 mstirq
&= ~MMCR_HBMSTIRQCTL_M_SERR_IRQ_ENB
;
1090 mstirq
&= ~MMCR_HBMSTIRQCTL_M_RPER_IRQ_ENB
;
1091 mstirq
&= ~MMCR_HBMSTIRQCTL_M_DPER_IRQ_ENB
;
1092 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBMSTIRQCTL
, mstirq
);
1094 tgtirq
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBTGTIRQCTL
);
1095 tgtirq
&= ~MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_ENB
;
1096 tgtirq
&= ~MMCR_HBTGTIRQCTL_T_APER_IRQ_ENB
;
1097 tgtirq
&= ~MMCR_HBTGTIRQCTL_T_DPER_IRQ_ENB
;
1098 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_HBTGTIRQCTL
, tgtirq
);
1100 pcihostmap
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
,
1102 /* Priority P2 (Master PIC IR1) */
1103 pcihostmap
&= ~MMCR_PCIHOSTMAP_PCI_IRQ_MAP
;
1104 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_PCIHOSTMAP
,
1111 elanpex_intr_disestablish(struct elansc_softc
*sc
)
1113 elanpex_shutdown(sc
->sc_pex
, 0);
1116 nmi_disestablish(sc
->sc_eih
);
1118 intr_disestablish(sc
->sc_eih
);
1124 elanpex_detach(device_t self
, int flags
)
1126 struct elansc_softc
*sc
= device_private(device_parent(self
));
1128 pmf_device_deregister(self
);
1129 elanpex_intr_disestablish(sc
);
1135 elanpar_intr_establish(device_t self
, struct elansc_softc
*sc
)
1137 uint8_t adddecctl
, wpvmap
;
1139 wpvmap
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_WPVMAP
);
1140 wpvmap
&= ~MMCR_WPVMAP_INT_MAP
;
1142 wpvmap
|= MMCR_WPVMAP_INT_NMI
;
1144 wpvmap
|= __SHIFTIN(__BIT(ELAN_IRQ
), MMCR_WPVMAP_INT_MAP
);
1145 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_WPVMAP
, wpvmap
);
1147 /* clear interrupt status */
1148 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WPVSTA
,
1149 MMCR_WPVSTA_WPV_STA
);
1151 /* establish interrupt */
1153 sc
->sc_pih
= nmi_establish(elanpar_nmi
, sc
);
1155 sc
->sc_pih
= elansc_intr_establish(self
, elanpar_intr
, sc
);
1157 adddecctl
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_ADDDECCTL
);
1158 adddecctl
|= MMCR_ADDDECCTL_WPV_INT_ENB
;
1159 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_ADDDECCTL
, adddecctl
);
1163 elanpar_shutdown(device_t self
, int flags
)
1166 struct elansc_softc
*sc
= device_private(device_parent(self
));
1168 for (i
= 0; i
< __arraycount(sc
->sc_textpar
); i
++) {
1169 if (sc
->sc_textpar
[i
] == -1)
1171 elansc_disable_par(sc
->sc_memt
, sc
->sc_memh
, sc
->sc_textpar
[i
]);
1172 sc
->sc_textpar
[i
] = -1;
1174 if (sc
->sc_pg0par
!= -1) {
1175 elansc_disable_par(sc
->sc_memt
, sc
->sc_memh
, sc
->sc_pg0par
);
1182 elanpar_deferred_attach(device_t self
)
1184 struct elansc_softc
*sc
= device_private(device_parent(self
));
1186 elansc_protect_text(self
, sc
);
1190 elanpar_attach(device_t parent
, device_t self
, void *aux
)
1192 struct elansc_softc
*sc
= device_private(parent
);
1194 aprint_naive(": Programmable Address Regions\n");
1195 aprint_normal(": AMD Elan SC520 Programmable Address Regions\n");
1197 elansc_print_1(self
, sc
, MMCR_WPVMAP
);
1198 elansc_print_all_par(self
, sc
->sc_memt
, sc
->sc_memh
);
1200 sc
->sc_pg0par
= elansc_protect_pg0(self
, sc
);
1201 /* XXX grotty hack to avoid trapping writes by x86_patch()
1202 * to the kernel text on a MULTIPROCESSOR kernel.
1204 config_interrupts(self
, elanpar_deferred_attach
);
1206 elansc_print_all_par(self
, sc
->sc_memt
, sc
->sc_memh
);
1208 elanpar_intr_establish(self
, sc
);
1210 elansc_print_1(self
, sc
, MMCR_ADDDECCTL
);
1212 if (!pmf_device_register1(self
, elanpar_suspend
, elanpar_resume
,
1214 aprint_error_dev(self
, "could not establish power hooks\n");
1218 elanpar_intr_disestablish(struct elansc_softc
*sc
)
1220 uint8_t adddecctl
, wpvmap
;
1222 /* disable interrupt, acknowledge it, disestablish our
1225 adddecctl
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_ADDDECCTL
);
1226 adddecctl
&= ~MMCR_ADDDECCTL_WPV_INT_ENB
;
1227 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_ADDDECCTL
, adddecctl
);
1229 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_WPVSTA
,
1230 MMCR_WPVSTA_WPV_STA
);
1233 nmi_disestablish(sc
->sc_pih
);
1235 intr_disestablish(sc
->sc_pih
);
1238 wpvmap
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_WPVMAP
);
1239 wpvmap
&= ~MMCR_WPVMAP_INT_MAP
;
1240 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_WPVMAP
, wpvmap
);
1244 elanpar_detach(device_t self
, int flags
)
1246 struct elansc_softc
*sc
= device_private(device_parent(self
));
1248 pmf_device_deregister(self
);
1250 elanpar_shutdown(self
, 0);
1252 elanpar_intr_disestablish(sc
);
1258 elansc_attach(device_t parent
, device_t self
, void *aux
)
1260 struct elansc_softc
*sc
= device_private(self
);
1261 struct pcibus_attach_args
*pba
= aux
;
1263 uint8_t cpuctl
, picicr
, ressta
;
1265 int pin
, reg
, shift
;
1271 sc
->sc_pc
= pba
->pba_pc
;
1272 sc
->sc_pciflags
= pba
->pba_flags
;
1273 sc
->sc_dmat
= pba
->pba_dmat
;
1274 sc
->sc_dmat64
= pba
->pba_dmat64
;
1275 sc
->sc_tag
= pci_make_tag(sc
->sc_pc
, 0, 0, 0);
1277 aprint_naive(": System Controller\n");
1278 aprint_normal(": AMD Elan SC520 System Controller\n");
1280 sc
->sc_iot
= pba
->pba_iot
;
1281 sc
->sc_memt
= pba
->pba_memt
;
1282 if (bus_space_map(sc
->sc_memt
, MMCR_BASE_ADDR
, PAGE_SIZE
, 0,
1283 &sc
->sc_memh
) != 0) {
1284 aprint_error_dev(sc
->sc_dev
, "unable to map registers\n");
1288 mutex_init(&sc
->sc_mtx
, MUTEX_DEFAULT
, IPL_HIGH
);
1290 rev
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, MMCR_REVID
);
1291 cpuctl
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_CPUCTL
);
1293 aprint_normal_dev(sc
->sc_dev
,
1294 "product %d stepping %d.%d, CPU clock %s\n",
1295 (rev
& REVID_PRODID
) >> REVID_PRODID_SHIFT
,
1296 (rev
& REVID_MAJSTEP
) >> REVID_MAJSTEP_SHIFT
,
1297 (rev
& REVID_MINSTEP
),
1298 elansc_speeds
[cpuctl
& CPUCTL_CPU_CLK_SPD_MASK
]);
1301 * SC520 rev A1 has a bug that affects the watchdog timer. If
1302 * the GP bus echo mode is enabled, writing to the watchdog control
1303 * register is blocked.
1305 * The BIOS in some systems (e.g. the Soekris net4501) enables
1306 * GP bus echo for various reasons, so we need to switch it off
1307 * when we talk to the watchdog timer.
1309 * XXX The step 1.1 (B1?) in my Soekris net4501 also has this
1310 * XXX problem, so we'll just enable it for all Elan SC520s
1311 * XXX for now. --thorpej@NetBSD.org
1313 if (1 || rev
== ((PRODID_ELAN_SC520
<< REVID_PRODID_SHIFT
) |
1314 (0 << REVID_MAJSTEP_SHIFT
) | (1)))
1318 * Determine cause of the last reset, and issue a warning if it
1319 * was due to watchdog expiry.
1321 ressta
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_RESSTA
);
1322 if (ressta
& RESSTA_WDT_RST_DET
)
1323 aprint_error_dev(sc
->sc_dev
,
1324 "WARNING: LAST RESET DUE TO WATCHDOG EXPIRATION!\n");
1325 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_RESSTA
, ressta
);
1327 elansc_print_1(self
, sc
, MMCR_MPICMODE
);
1328 elansc_print_1(self
, sc
, MMCR_SL1PICMODE
);
1329 elansc_print_1(self
, sc
, MMCR_SL2PICMODE
);
1330 elansc_print_1(self
, sc
, MMCR_PICICR
);
1332 sc
->sc_mpicmode
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
,
1334 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_MPICMODE
,
1335 sc
->sc_mpicmode
| __BIT(ELAN_IRQ
));
1337 sc
->sc_picicr
= bus_space_read_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_PICICR
);
1338 picicr
= sc
->sc_picicr
;
1339 if (elansc_pcinmi
|| elansc_wpvnmi
)
1340 picicr
|= MMCR_PICICR_NMI_ENB
;
1342 /* PC/AT compatibility */
1343 picicr
|= MMCR_PICICR_S1_GINT_MODE
|MMCR_PICICR_M_GINT_MODE
;
1345 bus_space_write_1(sc
->sc_memt
, sc
->sc_memh
, MMCR_PICICR
, picicr
);
1347 elansc_print_1(self
, sc
, MMCR_PICICR
);
1348 elansc_print_1(self
, sc
, MMCR_MPICMODE
);
1350 mutex_enter(&sc
->sc_mtx
);
1351 /* Set up the watchdog registers with some defaults. */
1352 elansc_wdogctl_write(sc
, WDTMRCTL_WRST_ENB
| WDTMRCTL_EXP_SEL30
);
1354 /* ...and clear it. */
1355 elansc_wdogctl_reset(sc
);
1356 mutex_exit(&sc
->sc_mtx
);
1358 if (!pmf_device_register1(self
, elansc_suspend
, elansc_resume
,
1360 aprint_error_dev(self
, "could not establish power hooks\n");
1363 /* Initialize GPIO pins array */
1364 for (pin
= 0; pin
< ELANSC_PIO_NPINS
; pin
++) {
1365 sc
->sc_gpio_pins
[pin
].pin_num
= pin
;
1366 sc
->sc_gpio_pins
[pin
].pin_caps
= GPIO_PIN_INPUT
|
1369 /* Read initial state */
1370 reg
= (pin
< 16 ? MMCR_PIODIR15_0
: MMCR_PIODIR31_16
);
1372 data
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, reg
);
1373 if ((data
& (1 << shift
)) == 0)
1374 sc
->sc_gpio_pins
[pin
].pin_flags
= GPIO_PIN_INPUT
;
1376 sc
->sc_gpio_pins
[pin
].pin_flags
= GPIO_PIN_OUTPUT
;
1377 if (elansc_gpio_pin_read(sc
, pin
) == 0)
1378 sc
->sc_gpio_pins
[pin
].pin_state
= GPIO_PIN_LOW
;
1380 sc
->sc_gpio_pins
[pin
].pin_state
= GPIO_PIN_HIGH
;
1383 /* Create controller tag */
1384 sc
->sc_gpio_gc
.gp_cookie
= sc
;
1385 sc
->sc_gpio_gc
.gp_pin_read
= elansc_gpio_pin_read
;
1386 sc
->sc_gpio_gc
.gp_pin_write
= elansc_gpio_pin_write
;
1387 sc
->sc_gpio_gc
.gp_pin_ctl
= elansc_gpio_pin_ctl
;
1391 elansc_rescan(sc
->sc_dev
, "elanparbus", NULL
);
1392 elansc_rescan(sc
->sc_dev
, "elanpexbus", NULL
);
1393 elansc_rescan(sc
->sc_dev
, "gpiobus", NULL
);
1396 * Hook up the watchdog timer.
1398 sc
->sc_smw
.smw_name
= device_xname(sc
->sc_dev
);
1399 sc
->sc_smw
.smw_cookie
= sc
;
1400 sc
->sc_smw
.smw_setmode
= elansc_wdog_setmode
;
1401 sc
->sc_smw
.smw_tickle
= elansc_wdog_tickle
;
1402 sc
->sc_smw
.smw_period
= 32; /* actually 32.54 */
1403 if (sysmon_wdog_register(&sc
->sc_smw
) != 0) {
1404 aprint_error_dev(sc
->sc_dev
,
1405 "unable to register watchdog with sysmon\n");
1407 elansc_attached
= true;
1408 elansc_rescan(sc
->sc_dev
, "pcibus", NULL
);
1412 elanpex_match(device_t parent
, cfdata_t match
, void *aux
)
1414 struct elansc_softc
*sc
= device_private(parent
);
1416 return sc
->sc_pex
== NULL
;
1420 elanpar_match(device_t parent
, cfdata_t match
, void *aux
)
1422 struct elansc_softc
*sc
= device_private(parent
);
1424 return sc
->sc_par
== NULL
;
1427 /* scan for new children */
1429 elansc_rescan(device_t self
, const char *ifattr
, const int *locators
)
1431 struct elansc_softc
*sc
= device_private(self
);
1433 if (ifattr_match(ifattr
, "elanparbus") && sc
->sc_par
== NULL
) {
1434 sc
->sc_par
= config_found_ia(sc
->sc_dev
, "elanparbus", NULL
,
1438 if (ifattr_match(ifattr
, "elanpexbus") && sc
->sc_pex
== NULL
) {
1439 sc
->sc_pex
= config_found_ia(sc
->sc_dev
, "elanpexbus", NULL
,
1443 if (ifattr_match(ifattr
, "gpiobus") && sc
->sc_gpio
== NULL
) {
1445 struct gpiobus_attach_args gba
;
1447 memset(&gba
, 0, sizeof(gba
));
1449 gba
.gba_gc
= &sc
->sc_gpio_gc
;
1450 gba
.gba_pins
= sc
->sc_gpio_pins
;
1451 gba
.gba_npins
= ELANSC_PIO_NPINS
;
1452 sc
->sc_gpio
= config_found_ia(sc
->sc_dev
, "gpiobus", &gba
,
1457 if (ifattr_match(ifattr
, "pcibus") && sc
->sc_pci
== NULL
) {
1458 struct pcibus_attach_args pba
;
1460 memset(&pba
, 0, sizeof(pba
));
1461 pba
.pba_iot
= sc
->sc_iot
;
1462 pba
.pba_memt
= sc
->sc_memt
;
1463 pba
.pba_dmat
= sc
->sc_dmat
;
1464 pba
.pba_dmat64
= sc
->sc_dmat64
;
1465 pba
.pba_pc
= sc
->sc_pc
;
1466 pba
.pba_flags
= sc
->sc_pciflags
;
1468 pba
.pba_bridgetag
= NULL
;
1469 sc
->sc_pci
= config_found_ia(self
, "pcibus", &pba
, pcibusprint
);
1475 CFATTACH_DECL3_NEW(elanpar
, 0,
1476 elanpar_match
, elanpar_attach
, elanpar_detach
, NULL
, NULL
, NULL
,
1477 DVF_DETACH_SHUTDOWN
);
1479 CFATTACH_DECL3_NEW(elanpex
, 0,
1480 elanpex_match
, elanpex_attach
, elanpex_detach
, NULL
, NULL
, NULL
,
1481 DVF_DETACH_SHUTDOWN
);
1483 CFATTACH_DECL3_NEW(elansc
, sizeof(struct elansc_softc
),
1484 elansc_match
, elansc_attach
, elansc_detach
, NULL
, elansc_rescan
,
1485 elansc_childdetached
, DVF_DETACH_SHUTDOWN
);
1489 elansc_gpio_pin_read(void *arg
, int pin
)
1491 struct elansc_softc
*sc
= arg
;
1495 reg
= (pin
< 16 ? MMCR_PIODATA15_0
: MMCR_PIODATA31_16
);
1498 mutex_enter(&sc
->sc_mtx
);
1499 data
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, reg
);
1500 mutex_exit(&sc
->sc_mtx
);
1502 return ((data
>> shift
) & 0x1);
1506 elansc_gpio_pin_write(void *arg
, int pin
, int value
)
1508 struct elansc_softc
*sc
= arg
;
1512 reg
= (pin
< 16 ? MMCR_PIODATA15_0
: MMCR_PIODATA31_16
);
1515 mutex_enter(&sc
->sc_mtx
);
1516 data
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, reg
);
1518 data
&= ~(1 << shift
);
1519 else if (value
== 1)
1520 data
|= (1 << shift
);
1522 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, reg
, data
);
1523 mutex_exit(&sc
->sc_mtx
);
1527 elansc_gpio_pin_ctl(void *arg
, int pin
, int flags
)
1529 struct elansc_softc
*sc
= arg
;
1533 reg
= (pin
< 16 ? MMCR_PIODIR15_0
: MMCR_PIODIR31_16
);
1535 mutex_enter(&sc
->sc_mtx
);
1536 data
= bus_space_read_2(sc
->sc_memt
, sc
->sc_memh
, reg
);
1537 if (flags
& GPIO_PIN_INPUT
)
1538 data
&= ~(1 << shift
);
1539 if (flags
& GPIO_PIN_OUTPUT
)
1540 data
|= (1 << shift
);
1542 bus_space_write_2(sc
->sc_memt
, sc
->sc_memh
, reg
, data
);
1543 mutex_exit(&sc
->sc_mtx
);