aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/via/vx900/sata.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/via/vx900/sata.c')
-rw-r--r--src/northbridge/via/vx900/sata.c275
1 files changed, 0 insertions, 275 deletions
diff --git a/src/northbridge/via/vx900/sata.c b/src/northbridge/via/vx900/sata.c
deleted file mode 100644
index 791133142f..0000000000
--- a/src/northbridge/via/vx900/sata.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
- *
- * 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, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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 <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-
-#include "vx900.h"
-
-/**
- * @file vx900/sata.c
- *
- * STATUS: Pretty good
- * The only issue is the SATA EPHY configuration. We do not know if it is board
- * specific or not. Otherwise, the SATA controller works without issues.
- */
-
-static void vx900_print_sata_errors(u32 flags)
-{
- /* Status flags */
- printk(BIOS_DEBUG, "\tPhyRdy %s\n",
- (flags & (1 << 16)) ? "changed" : "not changed");
- printk(BIOS_DEBUG, "\tCOMWAKE %s\n",
- (flags & (1 << 16)) ? "detected" : "not detected");
- printk(BIOS_DEBUG, "\tExchange as determined by COMINIT %s\n",
- (flags & (1 << 26)) ? "occurred" : "not occurred");
- printk(BIOS_DEBUG, "\tPort selector presence %s\n",
- (flags & (1 << 27)) ? "detected" : "not detected");
- /* Errors */
- if (flags & (1 << 0))
- printk(BIOS_DEBUG, "\tRecovered data integrity ERROR\n");
- if (flags & (1 << 1))
- printk(BIOS_DEBUG, "\tRecovered data communication ERROR\n");
- if (flags & (1 << 8))
- printk(BIOS_DEBUG, "\tNon-recovered Transient Data Integrity ERROR\n");
- if (flags & (1 << 9))
- printk(BIOS_DEBUG, "\tNon-recovered Persistent Communication or"
- "\tData Integrity ERROR\n");
- if (flags & (1 << 10))
- printk(BIOS_DEBUG, "\tProtocol ERROR\n");
- if (flags & (1 << 11))
- printk(BIOS_DEBUG, "\tInternal ERROR\n");
- if (flags & (1 << 17))
- printk(BIOS_DEBUG, "\tPHY Internal ERROR\n");
- if (flags & (1 << 19))
- printk(BIOS_DEBUG, "\t10B to 8B Decode ERROR\n");
- if (flags & (1 << 20))
- printk(BIOS_DEBUG, "\tDisparity ERROR\n");
- if (flags & (1 << 21))
- printk(BIOS_DEBUG, "\tCRC ERROR\n");
- if (flags & (1 << 22))
- printk(BIOS_DEBUG, "\tHandshake ERROR\n");
- if (flags & (1 << 23))
- printk(BIOS_DEBUG, "\tLink Sequence ERROR\n");
- if (flags & (1 << 24))
- printk(BIOS_DEBUG, "\tTransport State Transition ERROR\n");
- if (flags & (1 << 25))
- printk(BIOS_DEBUG, "\tUNRECOGNIZED FIS type\n");
-}
-
-static void vx900_dbg_sata_errors(struct device *dev)
-{
- /* Port 0 */
- if (pci_read_config8(dev, 0xa0) & (1 << 0)) {
- printk(BIOS_DEBUG, "Device detected in SATA port 0.\n");
- u32 flags = pci_read_config32(dev, 0xa8);
- vx900_print_sata_errors(flags);
- };
- /* Port 1 */
- if (pci_read_config8(dev, 0xa1) & (1 << 0)) {
- printk(BIOS_DEBUG, "Device detected in SATA port 1.\n");
- u32 flags = pci_read_config32(dev, 0xac);
- vx900_print_sata_errors(flags);
- };
-}
-
-typedef u8 sata_phy_config[64];
-
-static sata_phy_config reference_ephy = {
- 0x80, 0xb8, 0xf0, 0xfe, 0x40, 0x7e, 0xf6, 0xdd,
- 0x1a, 0x22, 0xa0, 0x10, 0x02, 0xa9, 0x7c, 0x7e,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x84, 0x8c,
- 0x75, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x40, 0xd0, 0x41, 0x40, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x40, 0x50, 0x41, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-static u32 sata_phy_read32(struct device *dev, u8 index)
-{
- /* The SATA PHY control registers are accessed by a funny index/value
- * scheme. Each byte (0,1,2,3) has its own 4-bit index */
- index = (index >> 2) & 0xf;
- u16 i16 = index | (index << 4) | (index << 8) | (index << 12);
- /* The index */
- pci_write_config16(dev, 0x68, i16);
- /* The value */
- return pci_read_config32(dev, 0x64);
-}
-
-static void sata_phy_write32(struct device *dev, u8 index, u32 val)
-{
- /* The SATA PHY control registers are accessed by a funny index/value
- * scheme. Each byte (0,1,2,3) has its own 4-bit index */
- index = (index >> 2) & 0xf;
- u16 i16 = index | (index << 4) | (index << 8) | (index << 12);
- /* The index */
- pci_write_config16(dev, 0x68, i16);
- /* The value */
- pci_write_config32(dev, 0x64, val);
-}
-
-static void vx900_sata_read_phy_config(struct device *dev, sata_phy_config cfg)
-{
- size_t i;
- u32 *data = (u32 *) cfg;
- for (i = 0; i < (sizeof(sata_phy_config)) >> 2; i++) {
- data[i] = sata_phy_read32(dev, i << 2);
- }
-}
-
-static void vx900_sata_write_phy_config(struct device *dev, sata_phy_config cfg)
-{
- size_t i;
- u32 *data = (u32 *) cfg;
- for (i = 0; i < (sizeof(sata_phy_config)) >> 2; i++) {
- sata_phy_write32(dev, i << 2, data[i]);
- }
-}
-
-static void vx900_sata_dump_phy_config(sata_phy_config cfg)
-{
- printk(BIOS_DEBUG, "SATA PHY config:\n");
- int i;
- for (i = 0; i < sizeof(sata_phy_config); i++) {
- unsigned char val;
- if ((i & 0x0f) == 0)
- printk(BIOS_DEBUG, "%02x:", i);
- val = cfg[i];
- if ((i & 7) == 0)
- printk(BIOS_DEBUG, " |");
- printk(BIOS_DEBUG, " %02x", val);
- if ((i & 0x0f) == 0x0f) {
- printk(BIOS_DEBUG, "\n");
- }
- }
-}
-
-/**
- * \brief VX900: Place the onboard SATA controller in Native IDE mode
- *
- * AHCI mode requires a sub-class of 0x06, and Interface of 0x0
- * SATA mode requires a sub-class of 0x06, and Interface of 0x00
- * Unfortunately, setting the class to SATA, will prevent us from modyfing the
- * interface register to an AHCI/SATA compliant value. Thus, payloads or OS may
- * not properly identify this as a SATA controller.
- * We could set the class code to 0x04, which would cause the interface register
- * to become 0x00, which represents a RAID controller. Unfortunately, when we do
- * this, SeaBIOS will skip this as a storage device, and we will not be able to
- * boot.
- * Our only option is to operate in IDE mode. We choose native IDE so that we
- * can freely assign an IRQ, and are not forced to use IRQ14
- */
-static void vx900_native_ide_mode(struct device *dev)
-{
- /* Disable subclass write protect */
- pci_update_config8(dev, 0x45, (u8)~(1 << 7), 0);
- /* Change the device class to IDE */
- pci_write_config16(dev, PCI_CLASS_DEVICE, PCI_CLASS_STORAGE_IDE);
- /* Re-enable subclass write protect */
- pci_or_config8(dev, 0x45, 1 << 7);
- /* Put it in native IDE mode */
- pci_write_config8(dev, PCI_CLASS_PROG, 0x8f);
-}
-
-static void vx900_sata_init(struct device *dev)
-{
- /* Enable SATA primary channel IO access */
- pci_or_config8(dev, 0x40, 1 << 1);
- /* Just SATA, so it makes sense to be in native SATA mode */
- vx900_native_ide_mode(dev);
-
- /* TP Layer Idle at least 20us before the Following Command */
- pci_or_config8(dev, 0x53, 1 << 7);
- /* Resend COMRESET When Recovering SATA Gen2 Device Error */
- pci_update_config8(dev, 0x62, ~(1 << 1), 1 << 7);
-
- /* Fix "PMP Device Can't Detect HDD Normally" (VIA Porting Guide)
- * SATA device detection will not work unless we clear these bits.
- * Without doing this, SeaBIOS (and potentially other payloads) will
- * timeout when detecting SATA devices */
- pci_update_config8(dev, 0x89, ~(1 << 3) | (1 << 6), 0);
-
- /* 12.7 Two Software Resets May Affect the System
- * When the software does the second reset before the first reset
- * finishes, it may cause the system hang. It would do one software
- * reset and check the BSY bit of one port only, and the BSY bit of
- * other port would be 1, then it does another software reset
- * immediately and causes the system hang.
- * This is because the first software reset doesn't finish, and the
- * state machine of the host controller conflicts, it can't finish the
- * second one anymore. The BSY bit of slave port would be always 1 after
- * the second software reset issues. BIOS should set the following
- * bit to avoid this issue. */
- pci_or_config8(dev, 0x80, 1 << 6);
-
- /* We need to set the EPHY values before doing anything with the link */
- sata_phy_config ephy;
- vx900_sata_read_phy_config(dev, ephy);
- if (1) {
- vx900_sata_dump_phy_config(ephy);
- vx900_sata_write_phy_config(dev, reference_ephy);
- } else {
- /* Enable TX and RX driving resistance */
- /* TX - 50 Ohm */
- ephy[1] &= ~(0x1f << 3);
- ephy[1] |= (1 << 7) | (8 << 3);
- /* RX - 50 Ohm */
- ephy[2] &= ~(0x1f << 3);
- ephy[2] |= (1 << 7) | (8 << 3);
- vx900_sata_write_phy_config(dev, ephy);
- }
-
- vx900_sata_read_phy_config(dev, ephy);
- vx900_sata_dump_phy_config(ephy);
-
- /* Clear error flags */
- pci_write_config32(dev, 0xa8, 0xffffffff);
- pci_write_config32(dev, 0xac, 0xffffffff);
-
- /* Start OOB link negotiation sequence */
- pci_or_config8(dev, 0xb9, 3 << 4);
-
- /* FIXME: From now on, we are just doing DEBUG stuff
- * Wait until PHY communication is enabled */
- u32 wloops = 0;
- while (!(pci_read_config8(dev, 0xa0) & (1 << 1)))
- wloops++;
- printk(BIOS_SPEW, "SATA wait loops: %u\n", wloops);
-
- vx900_dbg_sata_errors(dev);
-}
-
-static void vx900_sata_read_resources(struct device *dev)
-{
- pci_dev_read_resources(dev);
-}
-
-static struct device_operations vga_operations = {
- .read_resources = vx900_sata_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vx900_sata_init,
-};
-
-static const struct pci_driver chrome9hd_driver __pci_driver = {
- .ops = &vga_operations,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VX900_SATA,
-};