| /* SPDX-License-Identifier: GPL-2.0-only */ |
| |
| #include <bootstate.h> |
| #include <console/console.h> |
| #include <device/device.h> |
| #include <device/pci_ops.h> |
| #include <drivers/intel/gma/int15.h> |
| #include <southbridge/intel/bd82x6x/pch.h> |
| #include <southbridge/intel/common/gpio.h> |
| #include <superio/smsc/sch5545/sch5545.h> |
| |
| #include "sch5545_ec.h" |
| |
| #define SIO_PORT 0x2e |
| |
| #define GPIO_CHASSIS_ID0 1 |
| #define GPIO_VGA_CABLE_DET_L 4 |
| #define GPIO_SKU2 7 |
| #define GPIO_CHASSIS_ID1 17 |
| /* Internal USB header on mainboard */ |
| #define FLEXBAY_HEADER_CABLE_DET_L 20 |
| #define GPIO_BOARD_REV0 21 |
| /* Password clear jumper */ |
| #define GPIO_PSWD_CLR 31 |
| #define GPIO_SKU0 32 |
| #define GPIO_SKU1 35 |
| #define GPIO_CHASSIS_ID2 37 |
| /* Front panel presence */ |
| #define GPIO_FRONT_PANEL_PRESENT_L 39 |
| #define GPIO_INTRUDER_CABLE_DET_L 44 |
| #define GPIO_BOARD_REV1 46 |
| #define GPIO_BOARD_REV2 68 |
| /* Front USB 3.0 ports */ |
| #define GPIO_USB_HEADER_DET_L 69 |
| /* Differentiate between MT/DT on the Medium Tower and Desktop variants */ |
| #define GPIO_FRONT_PANEL_CHASSIS_DET_L 70 |
| /* |
| * This GPIO is connected to the transistor gate. If high, it will pull the |
| * HDA_SDO high. When strapped at PCH_PWROK it will enable the Flash Descriptor |
| * Security Override and disable ME after chipset bringup. Alternative method |
| * is to use the service jumper on the mainboard. |
| */ |
| #define GPIO_ME_MFG_MODE 74 |
| |
| /* These GPIOs are on SCH5545 */ |
| |
| /* Detect if the power switch cable is connected */ |
| #define SIO_GPIO_FP_CBL_DET_L 25 |
| /* Detect internal speaker connected to front cover */ |
| #define SIO_GPIO_PCSPKR_DET_L 31 |
| |
| static void mainboard_enable(struct device *dev) |
| { |
| int pin_sts; |
| install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_NONE, |
| GMA_INT15_PANEL_FIT_DEFAULT, |
| GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); |
| |
| pin_sts = get_gpio(GPIO_CHASSIS_ID0); |
| pin_sts |= get_gpio(GPIO_CHASSIS_ID1) << 1; |
| pin_sts |= get_gpio(GPIO_CHASSIS_ID2) << 2; |
| pin_sts |= get_gpio(GPIO_FRONT_PANEL_CHASSIS_DET_L) << 3; |
| |
| printk(BIOS_DEBUG, "Chassis type:"); |
| switch (pin_sts) { |
| case 0: |
| printk(BIOS_DEBUG, "MT\n"); |
| break; |
| case 3: |
| case 11: |
| printk(BIOS_DEBUG, "USFF\n"); |
| break; |
| case 4: |
| /* As per table in schematics, but don't know what this is */ |
| printk(BIOS_DEBUG, "Comoros\n"); |
| break; |
| case 1: |
| case 9: |
| case 5: |
| case 13: |
| printk(BIOS_DEBUG, "SFF\n"); |
| break; |
| case 8: |
| printk(BIOS_DEBUG, "DT\n"); |
| break; |
| default: |
| printk(BIOS_DEBUG, "Unknown chassis type %u\n", pin_sts); |
| break; |
| } |
| |
| pin_sts = get_gpio(GPIO_BOARD_REV0); |
| pin_sts |= get_gpio(GPIO_BOARD_REV1) << 1; |
| pin_sts |= get_gpio(GPIO_BOARD_REV2) << 2; |
| |
| printk(BIOS_DEBUG, "Board revision: %d\n", pin_sts); |
| |
| pin_sts = get_gpio(GPIO_SKU0); |
| pin_sts |= get_gpio(GPIO_SKU1) << 1; |
| pin_sts |= get_gpio(GPIO_SKU2) << 2; |
| |
| printk(BIOS_DEBUG, "SKU ID is %d:", pin_sts); |
| switch (pin_sts) { |
| case 0: |
| printk(BIOS_DEBUG, "TPM\n"); |
| break; |
| case 1: |
| printk(BIOS_DEBUG, "TCM\n"); |
| break; |
| case 2: |
| printk(BIOS_DEBUG, "Non TPM/TCM\n"); |
| break; |
| default: |
| printk(BIOS_DEBUG, "Unknown/reserved\n"); |
| break; |
| } |
| |
| printk(BIOS_DEBUG, "VGA cable %sconnected\n", |
| get_gpio(GPIO_VGA_CABLE_DET_L) ? "dis" : ""); |
| |
| printk(BIOS_DEBUG, "Flexbay %sattached to internal USB 2.0 header\n", |
| get_gpio(FLEXBAY_HEADER_CABLE_DET_L) ? "not " : ""); |
| |
| printk(BIOS_DEBUG, "Password clear jumper %sactive\n", |
| get_gpio(GPIO_PSWD_CLR) ? "in" : ""); |
| |
| if (!get_gpio(GPIO_FRONT_PANEL_PRESENT_L)) { |
| printk(BIOS_DEBUG, "Front panel cable connected\n"); |
| } else { |
| printk(BIOS_WARNING, "Front panel cable not connected!\n"); |
| printk(BIOS_WARNING, "Front USB 2.0 ports, SATA LED, microphone" |
| " and speaker jacks will not work!\n"); |
| printk(BIOS_WARNING, "Check the front panel cable!\n"); |
| } |
| |
| if (!get_gpio(GPIO_INTRUDER_CABLE_DET_L)) { |
| printk(BIOS_DEBUG, "Intruder cable connected\n"); |
| } else { |
| printk(BIOS_WARNING, "Intruder cable not connected!\n"); |
| printk(BIOS_WARNING, "Intrusion detection will not work!\n"); |
| printk(BIOS_WARNING, "Check the intruder cable!\n"); |
| } |
| |
| if (!get_gpio(GPIO_USB_HEADER_DET_L)) { |
| printk(BIOS_DEBUG, "Front USB 3.0 cable connected\n"); |
| } else { |
| printk(BIOS_WARNING, "Front USB 3.0 cable not connected!\n"); |
| printk(BIOS_WARNING, "Front USB 3.0 ports will not work!\n"); |
| printk(BIOS_WARNING, "Check the front USB 3.0 cable!\n"); |
| } |
| } |
| |
| static void mainboard_final(void *chip_info) |
| { |
| int pin_sts; |
| struct device *dev = pcidev_on_root(0x1f, 0); |
| const u8 pirq_routing = 11; |
| |
| pci_write_config8(dev, PIRQA_ROUT, pirq_routing); |
| pci_write_config8(dev, PIRQB_ROUT, pirq_routing); |
| pci_write_config8(dev, PIRQC_ROUT, pirq_routing); |
| pci_write_config8(dev, PIRQD_ROUT, pirq_routing); |
| |
| pci_write_config8(dev, PIRQE_ROUT, pirq_routing); |
| pci_write_config8(dev, PIRQF_ROUT, pirq_routing); |
| pci_write_config8(dev, PIRQG_ROUT, pirq_routing); |
| pci_write_config8(dev, PIRQH_ROUT, pirq_routing); |
| |
| pin_sts = sch5545_get_gpio(SIO_PORT, SIO_GPIO_FP_CBL_DET_L); |
| |
| if (pin_sts != -1) { |
| if (pin_sts) { |
| printk(BIOS_WARNING, "Power switch cable not connected!\n"); |
| printk(BIOS_WARNING, "Check power switch cable!\n"); |
| } else { |
| printk(BIOS_DEBUG, "Power switch cable connected\n"); |
| } |
| } |
| |
| pin_sts = sch5545_get_gpio(SIO_PORT, SIO_GPIO_PCSPKR_DET_L); |
| |
| if (pin_sts != -1) |
| printk(BIOS_DEBUG, "Internal chassis PC speaker %sconnected\n", |
| pin_sts ? "not " : ""); |
| } |
| |
| struct chip_operations mainboard_ops = { |
| .enable_dev = mainboard_enable, |
| .final = mainboard_final, |
| }; |
| |
| BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, sch5545_ec_hwm_init, NULL); |