soc/intel/skylake: Fix SATA booting to OS issue

SATA device remains unrecognized if connected at Port 2.

Port control and Status register (PCS) is by default set by
hardware to the disabled state as a result of an initial
power on reset. OS read PCS register during boot causes
disabling of SATA ports and can't detect any devices.

BRANCH=none
BUG=chrome-os-partner:59335
TEST=Build and boot SKL from SATA device connected at Port 2.

Change-Id: I4866ca44567f5024edaca2d48098af5b4c67a7ac
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-on: https://review.coreboot.org/17229
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Subrata Banik 2016-11-04 13:26:41 +05:30 committed by Martin Roth
parent 3d44d69f93
commit cb8849b686
2 changed files with 73 additions and 0 deletions

View File

@ -73,6 +73,7 @@ ramstage-y += pei_data.c
ramstage-y += pmc.c
ramstage-y += pmutil.c
ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c
ramstage-y += sata.c
ramstage-y += sd.c
ramstage-y += smbus.c
ramstage-y += smbus_common.c

View File

@ -0,0 +1,72 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2016 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_def.h>
#include <device/pci_ids.h>
#include <soc/ramstage.h>
static void *get_ahci_bar(void)
{
device_t dev = PCH_DEV_SATA;
uint32_t bar;
bar = pci_read_config32(dev, PCI_BASE_ADDRESS_5);
return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
}
/*
* SATA Port control and Status. By default, the SATA ports are set (by HW)
* to the disabled state (e.g. bits[3:0] == '0') as a result of an initial
* power on reset. When enabled by software as per SATA port mapping,
* the ports can transition between the on, partial and slumber states
* and can detect devices. When disabled, the port is in the off state and
* can't detect any devices.
*/
static void sata_final(device_t dev)
{
void *ahcibar = get_ahci_bar();
u8 port_impl;
dev = PCH_DEV_SATA;
/* Read Ports Implemented (GHC_PI) */
port_impl = read32(ahcibar + 0x0c);
port_impl = ~port_impl & 0x07;
/* Port enable */
pci_write_config8(dev, 0x92, port_impl);
}
static struct device_operations sata_ops = {
.read_resources = &pci_dev_read_resources,
.set_resources = &pci_dev_set_resources,
.enable_resources = &pci_dev_enable_resources,
.final = sata_final,
.ops_pci = &soc_pci_ops,
};
static const unsigned short pci_device_ids[] = {
0x9d03, /* SKL-U Base */
0x9d07, /* SKL-Y Premium, SKL-U Premium */
0xa282, /* KBL */
0
};
static const struct pci_driver pch_sata __pci_driver = {
.ops = &sata_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.devices = pci_device_ids,
};