blob: 81a5d7de53c510b0ee54d54a021b28f96840dd81 [file] [log] [blame]
Martin Rothbf6b83a2015-10-11 10:37:02 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * Copyright (C) 2013 Sage Electronic Engineering, LLC.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; version 2 of
10 * the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Martin Rothbf6b83a2015-10-11 10:37:02 +020016 */
17
18#include <arch/io.h>
19#include <console/console.h>
20#include <device/device.h>
21#include <device/pci.h>
22#include <device/pci_ids.h>
23#include "pch.h"
24
25typedef struct southbridge_intel_fsp_bd82x6x_config config_t;
26
27static void sata_init(struct device *dev)
28{
29 u32 reg32;
30 u16 reg16;
31 /* Get the chip configuration */
32 config_t *config = dev->chip_info;
33
34 printk(BIOS_DEBUG, "SATA: Initializing...\n");
35
36 if (config == NULL) {
37 printk(BIOS_ERR, "SATA: ERROR: Device not in devicetree.cb!\n");
38 return;
39 }
40
41 /* SATA configuration is handled by the FSP */
42
43 /* Enable BARs */
44 pci_write_config16(dev, PCI_COMMAND, 0x0007);
45
46 if (config->ide_legacy_combined) {
47 printk(BIOS_DEBUG, "SATA: Controller in combined mode.\n");
48
49 /* No AHCI: clear AHCI base */
50 pci_write_config32(dev, 0x24, 0x00000000);
51 /* And without AHCI BAR no memory decoding */
52 reg16 = pci_read_config16(dev, PCI_COMMAND);
53 reg16 &= ~PCI_COMMAND_MEMORY;
54 pci_write_config16(dev, PCI_COMMAND, reg16);
55 } else if(config->sata_ahci) {
56 u32 *abar;
57
58 printk(BIOS_DEBUG, "SATA: Controller in AHCI mode.\n");
59
60 /* Set Interrupt Line */
61 /* Interrupt Pin is set by D31IP.PIP */
62 pci_write_config8(dev, INTR_LN, 0x0a);
63
64 /* Initialize AHCI memory-mapped space */
65 abar = (u32 *)pci_read_config32(dev, PCI_BASE_ADDRESS_5);
66 printk(BIOS_DEBUG, "ABAR: %p\n", abar);
67 /* Enable AHCI Mode */
68 reg32 = read32(abar + 0x01);
69 reg32 |= (1 << 31);
70 write32(abar + 0x01, reg32);
71 } else {
72 printk(BIOS_DEBUG, "SATA: Controller in plain mode.\n");
73
74 /* Set Interrupt Line */
75 /* Interrupt Pin is set by D31IP.PIP */
76 pci_write_config8(dev, INTR_LN, 0xff);
77 }
78
79}
80
81static void sata_enable(device_t dev)
82{
83}
84
85static void sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
86{
87 if (!vendor || !device) {
88 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
89 pci_read_config32(dev, PCI_VENDOR_ID));
90 } else {
91 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
92 ((device & 0xffff) << 16) | (vendor & 0xffff));
93 }
94}
95
96static struct pci_operations sata_pci_ops = {
97 .set_subsystem = sata_set_subsystem,
98};
99
100static struct device_operations sata_ops = {
101 .read_resources = pci_dev_read_resources,
102 .set_resources = pci_dev_set_resources,
103 .enable_resources = pci_dev_enable_resources,
104 .init = sata_init,
105 .enable = sata_enable,
106 .scan_bus = 0,
107 .ops_pci = &sata_pci_ops,
108};
109
110static const unsigned short pci_device_ids[] = { 0x1c00, 0x1c01, 0x1c02, 0x1c03,
111 0x1e00, 0x1e01, 0x1e02, 0x1e03, 0x2323,
112 0 };
113
114static const struct pci_driver pch_sata __pci_driver = {
115 .ops = &sata_ops,
116 .vendor = PCI_VENDOR_ID_INTEL,
117 .devices = pci_device_ids,
118};