Re: SIS650+CPQ Presario 3045US details ...

Martin Diehl (lists@mdiehl.de)
Wed, 21 May 2003 21:12:15 +0200 (CEST)


On Tue, 20 May 2003, Davide Libenzi wrote:

> Below are reported details about my CPQ Presario 3045US with the new
> SIS650 chipset. I report how I changed the IRW routing functions, that
> makes my machine to work fine. I did that completely blindly since I
> couldn't find specs for the SIS650 chipset (Intel and AMD rulez about
> docs). As you can see both 0x6* and 0x4* requests are generated by the PCI
> world.

As already said, taken this way it has the potential to break older SiS
routing stuff. I'm too overloaded at the moment to do some deeper search,
but below I've hacked up some patch to make your observation work with the
existing pirq routing stuff without breaking the old one (yes, we need to
distinguish the router's revision id...)

For all 85C503 router functions except the rev 0x04 id doesn't change
anything, while in your case I've just taken what you've found. Patch
below is for 2.5.69 (-any IMHO) and I've tested here with my rev 0x01
system. Unfortunately the patch itself is rather unreadable due to the
interleaved switch-cases added and removed.

For testing I'd suggest to #define DEBUG in linux/arch/i386/pci/pci.h so
we get the routing table dumped and see how it works.

For the USB-HC enable using bit 6:

> if (!(x & 0x40))
> return 0;
[...]
> if (reg < 0x60)
> break;
> /* always mark OHCI enabled, as nothing else knows about this */
> x |= 0x40;

have you tried if it works without? That's just some special feature
documented for 0x62 only with old SiS 5595 southbridge. It may or may not
be the right thing to do with your 69x southbridge. Since it appears to
work for you, I've kept it there, but might be worth to try without.

Also, lspci -vxxx for this device (-d 1039:0008) would be interesting:

> 00:02.0 ISA bridge: Silicon Integrated Systems [SiS] 85C503/5513 (rev 04)
> Flags: bus master, medium devsel, latency 0

Martin

----------------------------------------

--- linux-2.5.69/arch/i386/pci/irq.c Wed May 7 09:13:25 2003
+++ v2.5.69/arch/i386/pci/irq.c Wed May 21 19:57:18 2003
@@ -258,106 +258,182 @@
}

/*
- * PIRQ routing for SiS 85C503 router used in several SiS chipsets
- * According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
- * the related registers work as follows:
- *
- * general: one byte per re-routable IRQ,
+ * PIRQ routing for SiS 85C503 router used in several SiS chipsets.
+ * We have to deal with the following issues here:
+ * - vendors have different ideas about the meaning of link values
+ * - some onboard devices (integrated in the chipset) have special
+ * links and are thus routed differently (i.e. not via PCI INTA-INTD)
+ * - different revision of the router have a different layout for
+ * the routing registers, particularly for the onchip devices
+ *
+ * For all routing registers the common thing is we have one byte
+ * per routeable link which is defined as:
* bit 7 IRQ mapping enabled (0) or disabled (1)
- * bits [6:4] reserved
+ * bits [6:4] reserved (sometimes used for onchip devices)
* bits [3:0] IRQ to map to
* allowed: 3-7, 9-12, 14-15
* reserved: 0, 1, 2, 8, 13
*
- * individual registers in device config space:
+ * The config-space registers located at 0x41/0x42/0x43/0x44 are
+ * always used to route the normal PCI INT A/B/C/D respectively.
+ * Apparently there are systems implementing PCI routing table using
+ * link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D.
+ * We try our best to handle both link mappings.
+ *
+ * Currently (2003-05-21) it appears most SiS chipsets follow the
+ * definition of routing registers from the SiS-5595 southbridge.
+ * According to the SiS 5595 datasheets the revision id's of the
+ * router (ISA-bridge) should be 0x01 or 0xb0.
+ *
+ * Furthermore we've also seen lspci dumps with revision 0x00 and 0xb1.
+ * Looks like these are used in a number of SiS 5xx/6xx/7xx chipsets.
+ * They seem to work with the current routing code. However there is
+ * some concern because of the two USB-OHCI HCs (original SiS 5595
+ * had only one). YMMV.
+ *
+ * Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1:
+ *
+ * 0x61: IDEIRQ:
+ * bits [6:5] must be written 01
+ * bit 4 channel-select primary (0), secondary (1)
+ *
+ * 0x62: USBIRQ:
+ * bit 6 OHCI function disabled (0), enabled (1)
+ *
+ * 0x6a: ACPI/SCI IRQ: bits 4-6 reserved
*
- * 0x41/0x42/0x43/0x44: PCI INT A/B/C/D - bits as in general case
+ * 0x7e: Data Acq. Module IRQ - bits 4-6 reserved
*
- * 0x61: IDEIRQ: bits as in general case - but:
- * bits [6:5] must be written 01
- * bit 4 channel-select primary (0), secondary (1)
+ * We support USBIRQ (in addition to INTA-INTD) and keep the
+ * IDE, ACPI and DAQ routing untouched as set by the BIOS.
*
- * 0x62: USBIRQ: bits as in general case - but:
- * bit 4 OHCI function disabled (0), enabled (1)
- *
- * 0x6a: ACPI/SCI IRQ - bits as in general case
+ * Currently the only reported exception is the new SiS 65x chipset
+ * which includes the SiS 69x southbridge. Here we have the 85C503
+ * router revision 0x04 and there are changes in the register layout
+ * mostly related to the different USB HCs with USB 2.0 support.
*
- * 0x7e: Data Acq. Module IRQ - bits as in general case
+ * Onchip routing for router rev-id 0x04 (try-and-error observation)
*
- * Apparently there are systems implementing PCI routing table using both
- * link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets
- * like 0x62 as link values for USBIRQ e.g. So there is no simple
- * "register = offset + pirq" relation.
- * Currently we support PCI INTA..D and USBIRQ and try our best to handle
- * both link mappings.
- * IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS).
+ * 0x60/0x61/0x62/0x63: 1xEHCI and 3xOHCI (companion) USB-HCs
+ * bit 6-4 usage is unclear, maybe like 5595
*/

-static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+#define PIRQ_SIS_IRQ_MASK 0x0f
+#define PIRQ_SIS_IRQ_DISABLE 0x80
+#define PIRQ_SIS_USB_ENABLE 0x40
+
+static inline int pirq_sis5595_onchip(int pirq)
{
- u8 x;
- int reg = pirq;
+ int ret = -1;

switch(pirq) {
+ case 0x62:
+ ret = PIRQ_SIS_USB_ENABLE; /* documented for 5595 */
+ break;
+
+ case 0x61:
+ case 0x6a:
+ case 0x7e:
+ printk(KERN_INFO "SiS pirq: IDE/ACPI/DAQ mapping not implemented\n");
+ /* fall thru */
+ default:
+ break;
+ }
+ return ret;
+}
+
+static inline int pirq_sis96x_onchip(int pirq)
+{
+ int ret = -1;
+
+ switch(pirq) {
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ case 0x63:
+ ret = PIRQ_SIS_USB_ENABLE; /* guessed from sis5595 */
+ break;
+
+ default:
+ break;
+ }
+ return ret;
+}
+
+/* return value:
+ * -1 on error
+ * 0 for PCI INTA-INTD
+ * 0 or enable bit mask to check or set for onchip functions
+ */
+
+static int pirq_sis_setup(struct pci_dev *router, int pirq, int *reg)
+{
+ u8 rev;
+ int ret = -1;
+
+ if (pirq >= 0x01 && pirq <= 0x04)
+ pirq += 0x40;
+
+ *reg = pirq;
+
+ if (pirq >= 0x41 && pirq <= 0x44) {
+ ret = 0;
+ }
+ else if (pci_read_config_byte(router, PCI_REVISION_ID, &rev) == 0) {
+
+ switch(rev) {
case 0x01:
- case 0x02:
- case 0x03:
+ case 0xb0:
+ case 0x00:
+ case 0xb1:
+ ret = pirq_sis5595_onchip(pirq);
+ break;
+
case 0x04:
- reg += 0x40;
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x44:
- case 0x62:
- pci_read_config_byte(router, reg, &x);
- if (reg != 0x62)
- break;
- if (!(x & 0x40))
- return 0;
+ ret = pirq_sis96x_onchip(pirq);
break;
- case 0x61:
- case 0x6a:
- case 0x7e:
- printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
- return 0;
- default:
- printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
- return 0;
+
+ default:
+ /* unknown revision - default to sis5595 */
+ printk(KERN_WARNING "SiS pirq: router rev=0x%02x\n", rev);
+ ret = pirq_sis5595_onchip(pirq);
+ break;
+ }
}
- return (x & 0x80) ? 0 : (x & 0x0f);
+ return ret;
+}
+
+static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+ u8 x;
+ int reg, check;
+
+ check = pirq_sis_setup(router, pirq, &reg);
+ if (check < 0)
+ return 0;
+
+ pci_read_config_byte(router, reg, &x);
+ if (check != 0 && !(x & check))
+ return 0;
+
+ return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK);
}

static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
u8 x;
- int reg = pirq;
+ int reg, set;
+
+ set = pirq_sis_setup(router, pirq, &reg);
+ if (set < 0)
+ return 0;
+
+ x = (irq & PIRQ_SIS_IRQ_MASK);
+ if (x == 0)
+ x = PIRQ_SIS_IRQ_DISABLE;
+ else
+ x |= set;

- switch(pirq) {
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- reg += 0x40;
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x44:
- case 0x62:
- x = (irq&0x0f) ? (irq&0x0f) : 0x80;
- if (reg != 0x62)
- break;
- /* always mark OHCI enabled, as nothing else knows about this */
- x |= 0x40;
- break;
- case 0x61:
- case 0x6a:
- case 0x7e:
- printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n");
- return 0;
- default:
- printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
- return 0;
- }
pci_write_config_byte(router, reg, x);

return 1;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/