summaryrefslogtreecommitdiff
path: root/sys/arch/arm
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2005-03-08 23:07:18 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2005-03-08 23:07:18 +0000
commite76e29c22c26da4326c0b202a2f81a788976794a (patch)
treedf26869e543faaa854a185f1b55f1e4fbbc5994c /sys/arch/arm
parent1f9e06e0d8fb2fc7ab67325a057aa639c30feddf (diff)
Enable or disable CF sockets at appropriate times, but be sure to
enable socket 0 power via GPIO. Socket 1 can be ignored for now. Initial diff, testing, and ok drahn@.
Diffstat (limited to 'sys/arch/arm')
-rw-r--r--sys/arch/arm/xscale/pxa2x0_pcic.c84
1 files changed, 79 insertions, 5 deletions
diff --git a/sys/arch/arm/xscale/pxa2x0_pcic.c b/sys/arch/arm/xscale/pxa2x0_pcic.c
index f0a7482b39a..a5600f6bd8f 100644
--- a/sys/arch/arm/xscale/pxa2x0_pcic.c
+++ b/sys/arch/arm/xscale/pxa2x0_pcic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_pcic.c,v 1.8 2005/02/23 00:05:38 drahn Exp $ */
+/* $OpenBSD: pxa2x0_pcic.c,v 1.9 2005/03/08 23:07:17 uwe Exp $ */
/*
* Copyright (c) 2005 Dale Rahn <drahn@openbsd.org>
*
@@ -277,14 +277,88 @@ void
pxapcic_socket_enable(pch)
pcmcia_chipset_handle_t pch;
{
- /* XXX */
+ struct pxapcic_socket *so = pch;
+ bus_space_tag_t iot = so->sc->sc_iot;
+ u_int16_t reg;
+
+ /* XXX fix scoop1 base address before trying that. */
+ if (so->socket == 1)
+ return;
+
+ /* XXX bit 2 was clear on boot with card preconfigured. */
+ reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_IRM);
+ bus_space_write_2(iot, so->scooph, SCOOP_REG_IRM, reg & ~0x0004);
+
+ /* Enable CF socket 0 power. */
+ if (so->socket == 0) {
+ reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_GPWR);
+ bus_space_write_2(iot, so->scooph, SCOOP_REG_GPWR,
+ reg | (1<<6)); /* SCOOP0_CF_POWER_C3000 */
+ delay(1000);
+ }
+
+ /* XXX */
+ reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_CPR);
+ reg = reg & ~(SCP_CPR_PWR|SCP_CPR_5V|SCP_CPR_3V);
+ bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg);
+
+ /*
+ * wait 300ms until power fails (Tpf). Then, wait 100ms since
+ * we are changing Vcc (Toff).
+ */
+ delay((300 + 100) * 1000);
+
+ /* Socket 1 supports only 5 V (which really is 3.3) for C3000? */
+ reg = reg | (SCP_CPR_PWR|SCP_CPR_5V);
+ bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg);
+
+ /*
+ * wait 100ms until power raise (Tpr) and 20ms to become
+ * stable (Tsu(Vcc)).
+ *
+ * some machines require some more time to be settled
+ * (another 200ms is added here).
+ */
+ delay((100 + 20 + 200) * 1000);
+
+ bus_space_write_2(iot, so->scooph, SCOOP_REG_CCR, SCP_CCR_RESET);
+ delay(10);
+ bus_space_write_2(iot, so->scooph, SCOOP_REG_CCR, 0);
+
+
+ /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
+
+ delay(20000);
+
+#if 0
+ printf("cardtype %d\n", h->pcmcia);
+#endif
}
void
pxapcic_socket_disable(pch)
pcmcia_chipset_handle_t pch;
{
- /* XXX */
+ struct pxapcic_socket *so = pch;
+ bus_space_tag_t iot = so->sc->sc_iot;
+ u_int16_t reg;
+
+ /* XXX fix scoop1 base address before trying that. */
+ if (so->socket == 1)
+ return;
+
+ /* XXX */
+ reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_CPR);
+ reg = reg & ~(SCP_CPR_PWR|SCP_CPR_5V|SCP_CPR_3V);
+ bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg);
+
+ /* Disable CF socket 0 power. */
+ if (so->socket == 0) {
+ reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_GPWR);
+ bus_space_write_2(iot, so->scooph, SCOOP_REG_GPWR,
+ reg & ~(1<<6)); /* SCOOP0_CF_POWER_C3000 */
+ delay(1000); /* XXX needed? */
+ }
}
#if 0
@@ -352,7 +426,7 @@ pxapcic_event_thread(void *arg)
}
sock->event_thread = NULL;
-
+
/* In case parent is waiting for us to exit. */
wakeup(sock->sc);
@@ -513,7 +587,7 @@ pxapcic_attach(struct device *parent, struct device *self, void *aux)
if (so->socket == 0)
pa = 0x10800000;
else if (so->socket == 1)
- pa = 0x14800000;
+ pa = 0x14800000; /* 0x08800040 */
else {
printf ("%s: invalid CF slot %d\n", sc->sc_dev.dv_xname,
i);