Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Dec 1999 10:45:51 +0900
From:      MIHIRA Sanpei Yoshiro <sanpei@sanpei.org>
To:        freebsd-mobile@FreeBSD.org
Subject:   [PCIC-TI-12xx] experimental patch for PCIC TI-12xx for 4-current
Message-ID:  <199912310145.KAA03263@lavender.yy.cs.keio.ac.jp>

next in thread | raw e-mail | index | archive | help
----Next_Part(Fri_Dec_31_10:45:50_1999)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi.

  I created experimental patch for TI-12xx PCIC, this patch was
originally from PAO3 sys/pci/pcic_p.{c,h}.

  Some NOTE-PC and it's BIOS did not initialize TI-12xx PCIC.  If it
was not, we can't play PC-Card in 4-current and 3-stable on that
NOTE-PC.

  Sorry, currently I only imported PAO3 code, and fixed some
differences from PAO3 and 4-current to compile it w/o error.
  I think it has some problems, but it is useful for NOTE-PC which
has poor BIOS....
  Current known problem in my NOTE-PC, NOTE-PC does not recognize
card insertion/removal after boot.  So I use pccardc power comment
like this:

	at insertion:
	STEP 1. 
	(insert PC-Card slot 1)
	STEP 2.
	# pccardc power 1 1		(power-on Slot1)

	at removal:
	STEP 1.
	# pccardc power 1 0		(power-off and virtual removal)
	STEP 2. 
	(remove PC-Card from slot 1)

P.S.
this patch is for 4-current.

Comments are welcome.

Thank you
MIHIRA Yoshiro
Yokohama, Japan

----Next_Part(Fri_Dec_31_10:45:50_1999)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

--- sys/pci/pcic_p.c.org	Tue Nov 30 00:44:15 1999
+++ sys/pci/pcic_p.c	Sun Dec 26 13:52:59 1999
@@ -32,6 +32,7 @@
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
+#include <sys/malloc.h>
 #include <pci/pcireg.h>
 #include <pci/pcivar.h>
 #include <pci/pcic_p.h>
@@ -45,6 +46,8 @@
 static void  pcic_pci_attach(pcici_t, int);
 
 static void  pd6832_legacy_init(pcici_t tag, int unit);
+static void  ti1xxx_pci_init(pcici_t tag, u_long pcic_pci_id);
+static void  generic_cardbus_attach(pcici_t tag, u_long id, int unit);
 
 static struct pci_device pcic_pci_driver = {
 	"pcic-pci",
@@ -53,6 +56,81 @@
 	&pcic_pci_count,
 	NULL
 };
+/*
+ * XXX
+ * Do our own re-probe protection until a configuration
+ * manager can do it for us.  This ensures that we don't
+ * reprobe a card already found by the PCI probes.
+ */
+#ifndef IO_PCIC1
+#define IO_PCIC1        0x3e0
+#endif
+#ifndef IO_PCIC2
+#define IO_PCIC2        0x3e2
+#endif
+#ifndef IO_PCIC3
+#define IO_PCIC3        0x3e4
+#endif
+
+static struct pcic_found
+{
+	u_long	port;
+	char	probed;
+} found[] =
+{
+	{ IO_PCIC1, 0 },
+	{ IO_PCIC2, 0 },
+	{ IO_PCIC3, 0 }
+};
+
+static u_long
+get_pci_pcic_addr(void)
+{
+	u_long	iobase = 0;
+	int	i;
+
+	for (i=0; i < sizeof(found)/sizeof(struct pcic_found); i++) {
+		if (!found[i].probed) {
+			found[i].probed = 1;
+			iobase = found[i].port;
+			break;
+		}
+	}
+	return iobase;
+}
+
+struct pci_pcic_info
+{
+	u_long	port;
+	int	slots;
+	pcici_t	tag;
+	struct pci_pcic_info *next;
+};
+
+static struct pci_pcic_info *info_list = NULL;
+
+static void
+set_pci_pcic_info(u_long iobase, pcici_t tag, int unit)
+{
+	struct pci_pcic_info *info;
+
+	for (info = info_list; info; info = info->next) {
+		if (info->port == iobase) {
+			info->slots++;
+			return;
+		}
+	}
+
+	info = malloc(sizeof *info, M_DEVBUF, M_NOWAIT);
+	if (info) {
+		info->port = iobase;
+		info->slots = 1;
+		info->tag = tag;
+		info->next = info_list;
+		info_list = info;
+	}
+}
+
 
 COMPAT_PCI_DRIVER(pcic_pci, pcic_pci_driver);
 
@@ -115,10 +193,32 @@
 pcic_pci_attach(pcici_t config_id, int unit)
 {
 	u_long pcic_type;	/* The vendor id of the PCI pcic */
+	u_long command;
 
 	pcic_type = pci_conf_read(config_id, PCI_ID_REG);
 
+	/* Init. CardBus/PC-card controllers as 16-bit PC-card controllers */
+
+	/* Place any per "slot" initialization here */
+	/*
+	 * In sys/pci/pcireg.h, PCI_COMMAND_STATUS_REG must be separated
+	 * PCI_COMMAND_REG(0x04) and PCI_STATUS_REG(0x06).
+	 * Takeshi Shibagaki(shiba@jp.freebsd.org).
+	 */
+        command = pci_cfgread(config_id, PCI_COMMAND_STATUS_REG, 4);
+        command |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE;
+        pci_cfgwrite(config_id, PCI_COMMAND_STATUS_REG, command, 4);
+
 	switch (pcic_type) { 
+        case PCI_DEVICE_ID_PCIC_TI1130:
+        case PCI_DEVICE_ID_PCIC_TI1131:
+        case PCI_DEVICE_ID_PCIC_TI1220:
+        case PCI_DEVICE_ID_PCIC_TI1221:
+        case PCI_DEVICE_ID_PCIC_TI1250:
+        case PCI_DEVICE_ID_PCIC_TI1251:
+                ti1xxx_pci_init(config_id, pcic_type);
+                generic_cardbus_attach(config_id, pcic_type, unit);
+                break;
 	case PCI_DEVICE_ID_PCIC_CLPD6832:
 		pd6832_legacy_init(config_id, unit);
 		break;
@@ -217,4 +317,157 @@
 	if (bootverbose)
 		printf("CardBus: Legacy PC-card 16bit I/O address [0x%x]\n",
 		       io_port);
+}
+/*
+ * TI1XXX PCI-CardBus Host Adapter specific function code.
+ * This function is separated from pcic_pci_attach().
+ * Support Device: TI1130,TI1131,TI1250,TI1220.
+ * Test Device: TI1221.
+ * Takeshi Shibagaki(shiba@jp.freebsd.org).
+ */
+static void
+ti1xxx_pci_init(pcici_t tag, u_long pcic_pci_id)
+{
+	u_long	syscntl,devcntl,cardcntl;
+	char	buf[128];
+	int 	ti113x = (pcic_pci_id == PCI_DEVICE_ID_PCIC_TI1130)
+			 || (pcic_pci_id == PCI_DEVICE_ID_PCIC_TI1131);
+
+	syscntl  = pci_cfgread(tag, TI113X_PCI_SYSTEM_CONTROL, 4);
+	devcntl  = pci_cfgread(tag, TI113X_PCI_DEVICE_CONTROL, 1);
+	cardcntl = pci_cfgread(tag, TI113X_PCI_CARD_CONTROL,   1);
+
+	switch(ti113x){
+		case 0 :
+			strcpy(buf, "TI12XX PCI Config Reg: ");
+			break;
+		case 1 :
+			strcpy(buf, "TI113X PCI Config Reg: ");
+			/*
+			 * Defalut card control register setting is PCI interrupt.
+			 * The method of this code switches PCI INT and ISA IRQ
+			 * by bit 7 of Bridge Control Register(Offset:0x3e,0x13e).
+			 * Takeshi Shibagaki(shiba@jp.freebsd.org)
+			 */
+			if(!(u_int8_t)tag->func) cardcntl |=  TI113X_CARDCNTL_PCI_IRQ_ENA;
+			cardcntl |= TI113X_CARDCNTL_PCI_IREQ;
+			cardcntl |= TI113X_CARDCNTL_PCI_CSC;
+			if(syscntl & TI113X_SYSCNTL_CLKRUN_ENA){
+				if(syscntl & TI113X_SYSCNTL_CLKRUN_SEL)
+					strcat(buf, "[clkrun irq 12]");
+				else
+					strcat(buf, "[clkrun irq 10]");
+			}
+			break;
+	}
+	if(cardcntl & TI113X_CARDCNTL_RING_ENA)
+		strcat(buf, "[ring enable]");
+	if(cardcntl & TI113X_CARDCNTL_SPKR_ENA)
+		strcat(buf, "[speaker enable]");
+	if(syscntl & TI113X_SYSCNTL_PWRSAVINGS)
+		strcat(buf, "[pwr save]");
+	switch(devcntl & TI113X_DEVCNTL_INTR_MASK){
+		case TI113X_DEVCNTL_INTR_ISA :
+			strcat(buf, "[CSC parallel isa irq]");
+			break;
+		case TI113X_DEVCNTL_INTR_SERIAL :
+			strcat(buf, "[CSC serial isa irq]");
+			break;
+		case TI113X_DEVCNTL_INTR_NONE :
+			strcat(buf, "[pci only]");
+			break;
+		case TI12XX_DEVCNTL_INTR_ALLSERIAL :
+			strcat(buf, "[FUNC pci int + CSC serial isa irq]");
+			break;
+	}
+#if 0
+	pci_cfgwrite(tag, TI113X_PCI_SYSTEM_CONTROL, syscntl, 4);
+	pci_cfgwrite(tag, TI113X_PCI_DEVICE_CONTROL, devcntl, 1);
+#endif /* 0 */
+	pci_cfgwrite(tag, TI113X_PCI_CARD_CONTROL,  cardcntl, 1);
+	if(ti113x){
+		cardcntl = pci_cfgread(tag, TI113X_PCI_CARD_CONTROL, 1);
+		switch(cardcntl & TI113X_CARDCNTL_MASK){
+			case TI113X_FUNC0_VALID :
+				if(!(u_int8_t)tag->func) strcat(buf, "[FUNC pci int]");
+				break;
+			case TI113X_FUNC1_VALID :
+				if((u_int8_t)tag->func) strcat(buf, "[FUNC pci int]");
+				break;
+		}
+	}
+	printf("%s\n",buf);
+}
+
+static void
+generic_cardbus_attach(pcici_t tag, u_long id, int unit)
+{
+	u_int8_t	func;
+	u_int16_t	brgcntl;
+	static u_long   iobase;	/* XXXX */
+
+
+#ifndef PCI_INTR_ENA
+	/*
+	 * This code exists to output ISA IRQ indicated in ExCA register(0x03).
+	 * The recent PAO needs this 3 lines absolutely. Don't remove!!
+	 * Takeshi Shibagaki(shiba@jp.freebsd.org).
+	 */
+	brgcntl = pci_cfgread(tag, CB_PCI_BRIDGE_CTRL, 2);
+	brgcntl |= CB_BCR_INT_EXCA;
+	pci_cfgwrite(tag, CB_PCI_BRIDGE_CTRL, brgcntl, 2);
+#else /* PCI_INTR_ENA */
+	/*
+	 * To output PCI INT indicated in Interrupt Pin Register(0x3d).
+	 * When each IRQ is routed to per slot, would be enable.
+	 * Takeshi Shibagaki(shiba@jp.freebsd.org).
+	 */
+	brgcntl = pci_cfgread(tag, CB_PCI_BRIDGE_CTRL, 2);
+	brgcntl &= ~CB_BCR_INT_EXCA;
+	pci_cfgwrite(tag, CB_PCI_BRIDGE_CTRL, brgcntl, 2);
+#endif /* PCI_INTR_ENA */
+
+	func = (u_int8_t)tag->func;
+
+	/* 16bit Legacy Mode Base Address */
+	if (func == 0) {
+#if 1
+		u_long  legacy16;
+
+		legacy16 = pci_cfgread(tag, CB_PCI_LEGACY16_IOADDR, 2)
+			& ~PCI_MAP_IO;
+		iobase = legacy16;	/* XXXX */
+		if (!legacy16) {
+			u_int   res;
+
+			legacy16 = get_pci_pcic_addr();
+			if (!legacy16) {
+				printf("not free legacy mode address\n");
+				return;
+			}
+			iobase = legacy16;	/* XXXX */
+			legacy16 |= PCI_MAP_IO;
+			pci_cfgwrite(tag, CB_PCI_LEGACY16_IOADDR, legacy16, 2);
+			res = pci_cfgread(tag, CB_PCI_LEGACY16_IOADDR, 2)
+				& ~PCI_MAP_IO;
+			if (bootverbose)
+				printf("pcic%d, Legacy PC-card "
+					"16bit I/O address is set to 0x%lx "
+					"(res: 0x%x)\n", 
+					unit, iobase, res);
+			iobase = res;
+		} else {
+			if (bootverbose)
+				printf("pcic%d, Legacy PC-card "
+					"16bit I/O address [0x%lx]\n", 
+					unit, iobase);
+		}
+	}
+#else
+	pci_cfgwrite(tag, CB_PCI_LEGACY16_IOADDR, 0, 4);
+#endif
+
+	set_pci_pcic_info(iobase, tag, unit);
+
+	return;
 }

----Next_Part(Fri_Dec_31_10:45:50_1999)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

--- sys/pci/pcic_p.h.org	Tue Nov 30 00:44:15 1999
+++ sys/pci/pcic_p.h	Sun Dec 26 13:52:59 1999
@@ -64,3 +64,82 @@
 #define	CLPD6832_NUM_REGS		2
 
 /* End of CL-PD6832 defines */
+/* Texas Instruments PCI-1130/1131 CardBus Controller */
+#define TI113X_PCI_SYSTEM_CONTROL	0x80	/* System Control */
+#define TI113X_PCI_RETRY_STATUS		0x90	/* Retry Status */
+#define TI113X_PCI_CARD_CONTROL		0x91	/* Card Control */
+#define TI113X_PCI_DEVICE_CONTROL	0x92	/* Device Control */
+#define TI113X_PCI_BUFFER_CONTROL	0x93	/* Buffer Control */
+#define TI113X_PCI_SOCKET_DMA0		0x94	/* Socket DMA Register 0 */
+#define TI113X_PCI_SOCKET_DMA1		0x98	/* Socket DMA Register 1 */
+
+/* Card control register (TI113X_SYSTEM_CONTROL == 0x80) */
+#define TI113X_SYSCNTL_VCC_PROTECT	0x00200000u
+#define TI113X_SYSCNTL_CLKRUN_SEL	0x00000080u
+#define	TI113X_SYSCNTL_PWRSAVINGS	0x00000040u
+#define TI113X_SYSCNTL_KEEP_CLK		0x00000002u
+#define TI113X_SYSCNTL_CLKRUN_ENA	0x00000001u
+
+/* Card control register (TI113X_CARD_CONTROL == 0x91) */
+#define TI113X_CARDCNTL_RING_ENA	0x80u
+#define TI113X_CARDCNTL_ZOOM_VIDEO	0x40u
+#define TI113X_CARDCNTL_PCI_IRQ_ENA	0x20u
+#define TI113X_CARDCNTL_PCI_IREQ	0x10u
+#define TI113X_CARDCNTL_PCI_CSC		0x08u
+#define	TI113X_CARDCNTL_MASK		(TI113X_CARDCNTL_PCI_IRQ_ENA | TI113X_CARDCNTL_PCI_IREQ | TI113X_CARDCNTL_PCI_CSC)
+#define	TI113X_FUNC0_VALID		TI113X_CARDCNTL_MASK
+#define	TI113X_FUNC1_VALID		(TI113X_CARDCNTL_PCI_IREQ | TI113X_CARDCNTL_PCI_CSC)
+/* Reserved bit				0x04u */
+#define TI113X_CARDCNTL_SPKR_ENA	0x02u
+#define TI113X_CARDCNTL_INT		0x01u
+
+/* Device control register (TI113X_DEVICE_CONTROL == 0x92) */
+#define	TI113X_DEVCNTL_5V_SOCKET	0x40u
+#define	TI113X_DEVCNTL_3V_SOCKET	0x20u
+#define	TI113X_DEVCNTL_INTR_MASK	0x06u
+#define	TI113X_DEVCNTL_INTR_NONE	0x00u
+#define	TI113X_DEVCNTL_INTR_ISA		0x02u
+#define	TI113X_DEVCNTL_INTR_SERIAL	0x04u
+/* TI112X specific code */
+#define	TI12XX_DEVCNTL_INTR_ALLSERIAL	0x06u
+/* Texas Instruments PCI-1130/1131 CardBus Controller */
+#define	TI113X_ExCA_IO_OFFSET0		0x36	/* Offset of I/O window */
+#define	TI113X_ExCA_IO_OFFSET1		0x38	/* Offset of I/O window */
+#define	TI113X_ExCA_MEM_WINDOW_PAGE	0x3C	/* Memory Window Page */
+
+/* sanpei */
+
+/* For Bridge Control register (CB_PCI_BRIDGE_CTRL) */
+#define CB_BCR_CB_RESET		0x0040
+#define CB_BCR_INT_EXCA		0x0080
+/* PCI Configuration Registers (common) */
+#define	CB_PCI_VENDOR_ID	0x00	/* vendor ID */
+#define	CB_PCI_DEVICE_ID	0x02	/* device ID */
+#define	CB_PCI_COMMAND		0x04	/* PCI command */
+#define	CB_PCI_STATUS		0x06	/* PCI status */
+#define	CB_PCI_REVISION_ID	0x08	/* PCI revision ID */
+#define	CB_PCI_CLASS		0x09	/* PCI class code */
+#define	CB_PCI_CACHE_LINE_SIZE	0x0c	/* Cache line size */
+#define	CB_PCI_LATENCY		0x0d	/* PCI latency timer */
+#define	CB_PCI_HEADER_TYPE	0x0e	/* PCI header type */
+#define	CB_PCI_BIST		0x0f	/* Built-in self test */
+#define	CB_PCI_SOCKET_BASE	0x10	/* Socket/ExCA base address reg. */
+#define	CB_PCI_CB_STATUS	0x16	/* CardBus Status */
+#define	CB_PCI_PCI_BUS_NUM	0x18	/* PCI bus number */
+#define	CB_PCI_CB_BUS_NUM	0x19	/* CardBus bus number */
+#define	CB_PCI_CB_SUB_BUS_NUM	0x1A	/* Subordinate CardBus bus number */
+#define	CB_PCI_CB_LATENCY	0x1A	/* CardBus latency timer */
+#define	CB_PCI_MEMBASE0		0x1C	/* Memory base register 0 */
+#define	CB_PCI_MEMLIMIT0	0x20	/* Memory limit register 0 */
+#define	CB_PCI_MEMBASE1		0x24	/* Memory base register 1 */
+#define	CB_PCI_MEMLIMIT1	0x28	/* Memory limit register 1 */
+#define	CB_PCI_IOBASE0		0x2C	/* I/O base register 0 */
+#define	CB_PCI_IOLIMIT0		0x30	/* I/O limit register 0 */
+#define	CB_PCI_IOBASE1		0x34	/* I/O base register 1 */
+#define	CB_PCI_IOLIMIT1		0x38	/* I/O limit register 1 */
+#define	CB_PCI_INT_LINE		0x3C	/* Interrupt Line */
+#define	CB_PCI_INT_PIN		0x3D	/* Interrupt Pin */
+#define	CB_PCI_BRIDGE_CTRL	0x3E	/* Bridge Control */
+#define	CB_PCI_SUBSYS_VENDOR_ID	0x40	/* Subsystem Vendor ID */
+#define	CB_PCI_SUBSYS_ID	0x42	/* Subsystem ID */
+#define	CB_PCI_LEGACY16_IOADDR	0x44	/* Legacy 16bit I/O address */

----Next_Part(Fri_Dec_31_10:45:50_1999)----


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199912310145.KAA03263>