/ util / superiotool / via.c
via.c
  1  /* SPDX-License-Identifier: GPL-2.0-or-later */
  2  
  3  #include "superiotool.h"
  4  
  5  #define DEVICE_ID_VT82C686_REG	0xe0
  6  #define DEVICE_REV_VT82C686_REG	0xe1
  7  
  8  #define DEVICE_ID_VT1211_REG    0x20
  9  #define DEVICE_REV_VT1211_REG   0x21
 10  
 11  static const struct superio_registers reg_table[] = {
 12  	{0x3c00, "VT82C686A/VT82C686B", {
 13  		{EOT}}},
 14  	{0x3c01, "VT1211", {
 15  		{NOLDN, NULL,
 16  			{0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
 17  			 0x2e,0x2f,EOT},
 18  			{0x3c,0x01,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,
 19  			 0x00,0x00,EOT}},
 20  		{0x0, "Floppy Disk Controller (FDC)",
 21  			{0x30,0x60,0x61,0x70,0x74,0xf0,0xf1,EOT},
 22  			{0x00,0x03,0xf0,0x06,0x01,0x00,0x00,EOT}},
 23  		{0x1, "Parallel Port (PP)",
 24  			{0x30,0x60,0x61,0x70,0x74,0xf0,EOT},
 25  			{0x03,0x03,0x78,0x05,0x00,0x00,EOT}},
 26  		{0x2, "Serial Port 1 (UART1)",
 27  			{0x30,0x60,0x61,0x70,0xf0,EOT},
 28  			{0x00,0x03,0xf8,0x04,0x00,EOT}},
 29  		{0x3, "Serial Port 2 (UART2)",
 30  			{0x30,0x60,0x61,0x70,0xf0,EOT},
 31  			{0x00,0x02,0xf8,0x03,0x00,EOT}},
 32  		{0x6, "MIDI",
 33  			{0x30,0x60,0x61,0x70,EOT},
 34  			{0x00,0x03,0x30,0x00,EOT}},
 35  		{0x7, "Game Port (GMP)",
 36  			{0x30,0x60,0x61,EOT},
 37  			{0x00,0x02,0x00,EOT}},
 38  		{0x8, "GPIO",
 39  			{0x30,0x60,0x61,0x70,0xf0,0xf1,0xf2,EOT},
 40  			{0x00,0xe9,0x00,0x00,0x00,0x00,0x00,EOT}},
 41  		{0x9, "Watch Dog (WDG)",
 42  			{0x30,0x60,0x61,0x70,0xf0,EOT},
 43  			{0x00,0xea,0x00,0x00,0x00,EOT}},
 44  		{0xa, "Wake-up Control (WUC)",
 45  			{0x30,0x60,0x61,0x70,EOT},
 46  			{0x00,0xeb,0x00,0x00,EOT}},
 47  		{0xb, "Hardware Monitor (HM)",
 48  			{0x30,0x60,0x61,0x70,EOT},
 49  			{0x00,0xec,0x00,0x00,EOT}},
 50  		{0xc, "Very Fast IR (VFIR)",
 51  			{0x30,0x60,0x61,0x70,0x74,0xf0,EOT},
 52  			{0x00,0xe8,0x00,0x00,0x06,0x00,EOT}},
 53  		{0xd, "Flash ROM (ROM)",
 54  			{0x30,0xf0,EOT},
 55  			{0x01,0x00,EOT}},
 56  		{EOT}}},
 57  	{EOT}
 58  };
 59  
 60  static uint8_t vt82c686_conf = 0;
 61  
 62  static int enter_conf_mode_via_vt82c686(void)
 63  {
 64  	struct pci_dev *dev;
 65  
 66  	dev = pci_dev_find(0x1106, 0x0686);
 67  	if (!dev) {
 68  		if (verbose)
 69  			printf("  PCI device 1106:0686 not found.\n");
 70  		return 1;
 71  	}
 72  
 73  	vt82c686_conf = pci_read_byte(dev, 0x85);
 74  	if (verbose)
 75  		printf("  Super I/O %sabled, Super I/O configuration %sabled\n",
 76  		       (vt82c686_conf & (1 << 0)) ? "en" : "dis",
 77  		       (vt82c686_conf & (1 << 1)) ? "en" : "dis");
 78  
 79  	/* If the Super I/O is not enabled, skip it. */
 80  	if (!(vt82c686_conf & (1 << 0)))
 81  		return 1;
 82  
 83  	/* Enable Super I/O configuration mode. */
 84  	pci_write_byte(dev, 0x85, vt82c686_conf | (1 << 1));
 85  
 86  	return 0;
 87  }
 88  
 89  static void exit_conf_mode_via_vt82c686(void)
 90  {
 91  	struct pci_dev *dev;
 92  
 93  	dev = pci_dev_find(0x1106, 0x0686);
 94  	if (!dev) {
 95  		printf("Bug: PCI device 1106:0686 not found during shutdown.\n"
 96  		       "Please report to coreboot@coreboot.org.\n");
 97  		return;
 98  	}
 99  
100  	/* Restore (disable?) Super I/O configuration mode setting. */
101  	pci_write_byte(dev, 0x85, vt82c686_conf);
102  }
103  
104  void probe_idregs_via(uint16_t port)
105  {
106  	uint16_t id;
107  	uint8_t devid;
108  	uint8_t rev;
109  
110  	if (port == 0x3f0) {
111  		probing_for("VIA", "(init=vt82c686) ", port);
112  		if (enter_conf_mode_via_vt82c686())
113  			return;
114  
115  		devid = regval(port, DEVICE_ID_VT82C686_REG);
116  		rev = regval(port, DEVICE_REV_VT82C686_REG);
117  		id = devid << 8;
118  
119  		if (superio_unknown(reg_table, id)) {
120  			if (verbose)
121  				printf(NOTFOUND "id=0x%02x, rev=0x%02x\n", devid, rev);
122  		} else {
123  			printf("Found VIA %s (id=0x%02x, rev=0x%02x) at 0x%x\n",
124  			       get_superio_name(reg_table, id), devid, rev, port);
125  			chip_found = 1;
126  		}
127  		exit_conf_mode_via_vt82c686();
128  		if (chip_found)
129  			return;
130  	} else {
131  		probing_for("VIA", "(init=0x87,0x87) ", port);
132  		enter_conf_mode_winbond_fintek_ite_8787(port);
133  
134  	        devid = regval(port, DEVICE_ID_VT1211_REG);
135  		rev = regval(port, DEVICE_REV_VT1211_REG);
136  		id = (devid << 8) | 1;
137  
138  		if (superio_unknown(reg_table, id)) {
139  			if (verbose)
140  				printf(NOTFOUND "id=0x%02x, rev=0x%02x\n", devid, rev);
141  		} else {
142  			printf("Found VIA %s (id=0x%02x, rev=0x%02x) at 0x%x\n",
143  			       get_superio_name(reg_table, id), devid, rev, port);
144  			chip_found = 1;
145  			dump_superio("VIA", reg_table, port, id, LDN_SEL);
146  		}
147  	}
148  
149  	exit_conf_mode_winbond_fintek_ite_8787(port);
150  }
151  
152  void print_via_chips(void)
153  {
154  	print_vendor_chips("VIA", reg_table);
155  }