From 42e5f2f287732e7f19d2a266a882ece0c09732c3 Mon Sep 17 00:00:00 2001
From: Warner Losh <imp@FreeBSD.org>
Date: Sat, 4 Jan 2003 17:26:35 +0000
Subject: [PATCH] Merge from P4: o Update copyright. o Add a tunable to allow
 the ti12xx to initialize the pci clock.  Some rare   cards need it. o rename
 67xx -> 6729 since there's really only one chip in this family. o from
 pcic_pci_pd6729_init call the routing code o Fix some comments out routing on
 the TI-1130 class (1030, 1130 and 1131)

MFC: After RE@ says it is ok.
---
 sys/pccard/pcic_pci.c | 69 ++++++++++++++++++++++++++-----------------
 1 file changed, 42 insertions(+), 27 deletions(-)

diff --git a/sys/pccard/pcic_pci.c b/sys/pccard/pcic_pci.c
index 43544b0daf12..36ad50883f6b 100644
--- a/sys/pccard/pcic_pci.c
+++ b/sys/pccard/pcic_pci.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001 M. Warner Losh.  All Rights Reserved.
+ * Copyright (c) 2000, 2002 M. Warner Losh.  All Rights Reserved.
  * Copyright (c) 1997 Ted Faber All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,6 +111,15 @@ a value of 2, while chips installed in a laptop need a value of 1 (which is\n\
 also the default).  This is similar to hw.pcic.intr_path, but separate so\n\
 that it can default to ISA when intr_path defaults to PCI.");
 
+static int pcic_ti12xx_enable_pci_clock = 0;
+TUNABLE_INT("hw.pcic.ti12xx_enable_pci_clock", &pcic_ti12xx_enable_pci_clock);
+SYSCTL_INT(_hw_pcic, OID_AUTO, ti12xx_enable_pci_clock, CTLFLAG_RD,
+    &pcic_ti12xx_enable_pci_clock, 0,
+  "Some TI-12xx parts need to have the PCI clock enabled.  These designs do\n\
+not provide a clock themselves.  Most of the reference boards have the\n\
+required oscillator parts, so the number of machines that needs this to be\n\
+set is vanishingly small.");
+
 static void pcic_pci_cardbus_init(device_t);
 static pcic_intr_way_t pcic_pci_gen_func;
 static pcic_intr_way_t pcic_pci_gen_csc;
@@ -124,9 +133,9 @@ static pcic_intr_way_t pcic_pci_oz68xx_func;
 static pcic_intr_way_t pcic_pci_oz68xx_csc;
 static pcic_init_t pcic_pci_oz68xx_init;
 
-static pcic_intr_way_t pcic_pci_pd67xx_func;
-static pcic_intr_way_t pcic_pci_pd67xx_csc;
-static pcic_init_t pcic_pci_pd67xx_init;
+static pcic_intr_way_t pcic_pci_pd6729_func;
+static pcic_intr_way_t pcic_pci_pd6729_csc;
+static pcic_init_t pcic_pci_pd6729_init;
 
 static pcic_intr_way_t pcic_pci_pd68xx_func;
 static pcic_intr_way_t pcic_pci_pd68xx_csc;
@@ -161,11 +170,11 @@ static struct pcic_chip pcic_pci_oz68xx_chip = {
 	pcic_pci_oz68xx_init
 };
 
-static struct pcic_chip pcic_pci_pd67xx_chip = {
-	pcic_pci_pd67xx_func,
-	pcic_pci_pd67xx_csc,
+static struct pcic_chip pcic_pci_pd6729_chip = {
+	pcic_pci_pd6729_func,
+	pcic_pci_pd6729_csc,
 	pcic_pci_gen_mapirq,
-	pcic_pci_pd67xx_init
+	pcic_pci_pd6729_init
 };
 
 static struct pcic_chip pcic_pci_pd68xx_chip = {
@@ -222,9 +231,9 @@ struct pcic_pci_table
 	struct pcic_chip *chip;
 } pcic_pci_devs[] = {
 	{ PCIC_ID_OMEGA_82C094, "Omega 82C094G",
-	  PCIC_I82365, PCIC_DF_POWER, &pcic_pci_pd67xx_chip },
+	  PCIC_I82365, PCIC_DF_POWER, &pcic_pci_pd6729_chip },
 	{ PCIC_ID_CLPD6729, "Cirrus Logic PD6729/6730 PCI-PCMCIA Bridge",
-	  PCIC_PD6729, PCIC_PD_POWER, &pcic_pci_pd67xx_chip },
+	  PCIC_PD6729, PCIC_PD_POWER, &pcic_pci_pd6729_chip },
 	{ PCIC_ID_CLPD6832, "Cirrus Logic PD6832 PCI-CardBus Bridge",
 	  PCIC_PD673X, PCIC_CARDBUS_POWER, &pcic_pci_pd68xx_chip },
 	{ PCIC_ID_CLPD6833, "Cirrus Logic PD6833 PCI-CardBus Bridge",
@@ -449,7 +458,7 @@ pcic_pci_oz68xx_init(device_t dev)
  * with them to know for sure.
  */
 static int
-pcic_pci_pd67xx_func(struct pcic_slot *sp, enum pcic_intr_way way)
+pcic_pci_pd6729_func(struct pcic_slot *sp, enum pcic_intr_way way)
 {
 	/*
 	 * For pci interrupts, we need to set bit 3 of extension register
@@ -465,7 +474,7 @@ pcic_pci_pd67xx_func(struct pcic_slot *sp, enum pcic_intr_way way)
 }
 
 static int
-pcic_pci_pd67xx_csc(struct pcic_slot *sp, enum pcic_intr_way way)
+pcic_pci_pd6729_csc(struct pcic_slot *sp, enum pcic_intr_way way)
 {
 	/*
 	 * For pci interrupts, we need to set bit 4 of extension register
@@ -482,12 +491,15 @@ pcic_pci_pd67xx_csc(struct pcic_slot *sp, enum pcic_intr_way way)
 
 
 static void
-pcic_pci_pd67xx_init(device_t dev)
+pcic_pci_pd6729_init(device_t dev)
 {
 	struct pcic_softc *sc = device_get_softc(dev);
 
-	if (sc->csc_route == pcic_iw_pci || sc->func_route == pcic_iw_pci)
-		device_printf(dev, "PD67xx maybe broken for PCI routing.\n");
+	/*
+	 * Tell the chip to do its routing thing.
+	 */
+	pcic_pci_pd6729_func(&sc->slots[0], sc->func_route);
+	pcic_pci_pd6729_csc(&sc->slots[0], sc->csc_route);
 }
 
 /*
@@ -608,12 +620,13 @@ pcic_pci_ti113x_func(struct pcic_slot *sp, enum pcic_intr_way way)
 
 	/*
 	 * The TI-1130 (and 1030 and 1131) have a different interrupt
-	 * routing control than the newer cards.  assume we're not
-	 * routing PCI, but enable as necessary when we find someone
-	 * uses PCI interrupts.  In order to get any pci interrupts,
-	 * PCI_IRQ_ENA (bit 5) must be set.  If either PCI_IREQ (bit
-	 * 4) or PCI_CSC (bit 3) are set, then set bit 5 at the same
-	 * time, since setting them enables the PCI interrupt routing.
+	 * routing control than the newer chips.  assume we're not
+	 * routing either csc or func interrupts via PCI, but enable
+	 * as necessary when we find someone uses PCI interrupts.  In
+	 * order to get any pci interrupts, PCI_IRQ_ENA (bit 5) must
+	 * be set.  If either PCI_IREQ (bit 4) or PCI_CSC (bit 3) are
+	 * set, then set bit 5 at the same time, since setting them
+	 * enables the PCI interrupt routing.
 	 *
 	 * It also appears necessary to set the function routing bit
 	 * in the bridge control register, but cardbus_init does that
@@ -696,16 +709,18 @@ pcic_pci_ti12xx_func(struct pcic_slot *sp, enum pcic_intr_way way)
 			    devcntl, 1);
 			syscntl |= TI113X_SYSCNTL_INTRTIE;
 		}
-#if 0
+
 		/*
 		 * I've had reports that we need the pci clock enabled,
-		 * but I'm unsure how wise this is in general, so it
-		 * is ifdef'd out at the moment
+		 * provide a hook to do so.  The number of cards that
+		 * require this is quite small.
 		 */
-		syscntl |= TI12XX_SYSCNTL_PCI_CLOCK;
-		pci_write_config(dev, TI113X_PCI_SYSTEM_CONTROL, syscntl, 4);
+		if (pcic_ti12xx_enable_pci_clock) {
+			syscntl |= TI12XX_SYSCNTL_PCI_CLOCK;
+			pci_write_config(dev, TI113X_PCI_SYSTEM_CONTROL,
+			    syscntl, 4);
+		}
 
-#endif
 		/*
 		 * Some PCI add-in cards don't have good EEPROMs on them,
 		 * so they get this MUX register wrong.  The MUX register