192 lines
5.4 KiB
C
192 lines
5.4 KiB
C
/* 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);
|