coreboot/src/southbridge/intel/i82801gx/sata.c
<<
>>
Prefs
   1/*
   2 * This file is part of the coreboot project.
   3 *
   4 * Copyright (C) 2008-2009 coresystems GmbH
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation; version 2 of
   9 * the License.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  19 */
  20
  21#include <console/console.h>
  22#include <device/device.h>
  23#include <device/pci.h>
  24#include <device/pci_ids.h>
  25#include "i82801gx.h"
  26
  27typedef struct southbridge_intel_i82801gx_config config_t;
  28
  29static void sata_init(struct device *dev)
  30{
  31        u32 reg32;
  32        u16 reg16;
  33        /* Get the chip configuration */
  34        config_t *config = dev->chip_info;
  35
  36        printk(BIOS_DEBUG, "i82801gx_sata: initializing...\n");
  37
  38        if (config == NULL) {
  39                printk(BIOS_ERR, "i82801gx_sata: error: device not in devicetree.cb!\n");
  40                return;
  41        }
  42
  43        /* SATA configuration */
  44
  45        /* Enable BARs */
  46        pci_write_config16(dev, PCI_COMMAND, 0x0007);
  47
  48        if (config->ide_legacy_combined) {
  49                printk(BIOS_DEBUG, "SATA controller in combined mode.\n");
  50                /* No AHCI: clear AHCI base */
  51                pci_write_config32(dev, 0x24, 0x00000000);
  52                /* And without AHCI BAR no memory decoding */
  53                reg16 = pci_read_config16(dev, PCI_COMMAND);
  54                reg16 &= ~PCI_COMMAND_MEMORY;
  55                pci_write_config16(dev, PCI_COMMAND, reg16);
  56
  57                pci_write_config8(dev, 0x09, 0x80);
  58
  59                /* Set timings */
  60                pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
  61                                IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
  62                pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
  63                                IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
  64                                IDE_PPE0 | IDE_IE0 | IDE_TIME0);
  65
  66                /* Sync DMA */
  67                pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
  68                pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
  69
  70                /* Set IDE I/O Configuration */
  71                reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
  72                pci_write_config32(dev, IDE_CONFIG, reg32);
  73
  74                /* Combine IDE - SATA configuration */
  75                pci_write_config8(dev, 0x90, 0x02);
  76
  77                /* Port 0 & 1 enable */
  78                pci_write_config8(dev, 0x92, 0x0f);
  79
  80                /* SATA Initialization register */
  81                pci_write_config32(dev, 0x94, 0x5a000180);
  82        } else if(config->sata_ahci) {
  83                printk(BIOS_DEBUG, "SATA controller in AHCI mode.\n");
  84                /* Allow both Legacy and Native mode */
  85                pci_write_config8(dev, 0x09, 0x8f);
  86
  87                /* Set Interrupt Line */
  88                /* Interrupt Pin is set by D31IP.PIP */
  89                pci_write_config8(dev, INTR_LN, 0x0a);
  90
  91                /* Set timings */
  92                pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
  93                                IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
  94                                IDE_PPE0 | IDE_IE0 | IDE_TIME0);
  95                pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
  96                                IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
  97
  98                /* Sync DMA */
  99                pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
 100                pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
 101
 102                /* Set IDE I/O Configuration */
 103                reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
 104                pci_write_config32(dev, IDE_CONFIG, reg32);
 105
 106                /* Set Sata Controller Mode. */
 107                pci_write_config8(dev, 0x90, 0x40); // 40=AHCI
 108
 109                /* Port 0 & 1 enable */
 110                pci_write_config8(dev, 0x92, 0x0f);
 111
 112                /* SATA Initialization register */
 113                pci_write_config32(dev, 0x94, 0x1a000180);
 114        } else {
 115                printk(BIOS_DEBUG, "SATA controller in plain mode.\n");
 116                /* Set Sata Controller Mode. No Mapping(?) */
 117                pci_write_config8(dev, 0x90, 0x00);
 118
 119                /* No AHCI: clear AHCI base */
 120                pci_write_config32(dev, 0x24, 0x00000000);
 121
 122                /* And without AHCI BAR no memory decoding */
 123                reg16 = pci_read_config16(dev, PCI_COMMAND);
 124                reg16 &= ~PCI_COMMAND_MEMORY;
 125                pci_write_config16(dev, PCI_COMMAND, reg16);
 126
 127                /* Native mode capable on both primary and secondary (0xa)
 128                 * or'ed with enabled (0x50) = 0xf
 129                 */
 130                pci_write_config8(dev, 0x09, 0x8f);
 131
 132                /* Set Interrupt Line */
 133                /* Interrupt Pin is set by D31IP.PIP */
 134                pci_write_config8(dev, INTR_LN, 0xff);
 135
 136                /* Set timings */
 137                pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
 138                                IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
 139                                IDE_PPE0 | IDE_IE0 | IDE_TIME0);
 140                pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
 141                                IDE_SITRE | IDE_ISP_3_CLOCKS |
 142                                IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
 143
 144                /* Sync DMA */
 145                pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
 146                pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
 147
 148                /* Set IDE I/O Configuration */
 149                reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
 150                pci_write_config32(dev, IDE_CONFIG, reg32);
 151
 152                /* Port 0 & 1 enable XXX */
 153                pci_write_config8(dev, 0x92, 0x15);
 154
 155                /* SATA Initialization register */
 156                pci_write_config32(dev, 0x94, 0x1a000180);
 157        }
 158
 159        /* All configurations need this SATA initialization sequence */
 160        pci_write_config8(dev, 0xa0, 0x40);
 161        pci_write_config8(dev, 0xa6, 0x22);
 162        pci_write_config8(dev, 0xa0, 0x78);
 163        pci_write_config8(dev, 0xa6, 0x22);
 164        pci_write_config8(dev, 0xa0, 0x88);
 165        reg32 = pci_read_config32(dev, 0xa4);
 166        reg32 &= 0xc0c0c0c0;
 167        reg32 |= 0x1b1b1212;
 168        pci_write_config32(dev, 0xa4, reg32);
 169        pci_write_config8(dev, 0xa0, 0x8c);
 170        reg32 = pci_read_config32(dev, 0xa4);
 171        reg32 &= 0xc0c0ff00;
 172        reg32 |= 0x121200aa;
 173        pci_write_config32(dev, 0xa4, reg32);
 174        pci_write_config8(dev, 0xa0, 0x00);
 175
 176        pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
 177
 178        /* Sata Initialization Register */
 179        reg32 = pci_read_config32(dev, 0x94);
 180        reg32 |= (1 << 30); // due to some bug
 181        pci_write_config32(dev, 0x94, reg32);
 182}
 183
 184static void sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
 185{
 186        if (!vendor || !device) {
 187                pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
 188                                pci_read_config32(dev, PCI_VENDOR_ID));
 189        } else {
 190                pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
 191                                ((device & 0xffff) << 16) | (vendor & 0xffff));
 192        }
 193}
 194
 195static struct pci_operations sata_pci_ops = {
 196        .set_subsystem    = sata_set_subsystem,
 197};
 198
 199static struct device_operations sata_ops = {
 200        .read_resources         = pci_dev_read_resources,
 201        .set_resources          = pci_dev_set_resources,
 202        .enable_resources       = pci_dev_enable_resources,
 203        .init                   = sata_init,
 204        .scan_bus               = 0,
 205        .enable                 = i82801gx_enable,
 206        .ops_pci                = &sata_pci_ops,
 207};
 208
 209/* Desktop Non-AHCI and Non-RAID Mode */
 210/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
 211static const struct pci_driver i82801gx_sata_normal_driver __pci_driver = {
 212        .ops    = &sata_ops,
 213        .vendor = PCI_VENDOR_ID_INTEL,
 214        .device = 0x27c0,
 215};
 216
 217/* Mobile Non-AHCI and Non-RAID Mode */
 218/* 82801GBM/GHM (ICH7-M/ICH7-M DH) */
 219static const struct pci_driver i82801gx_sata_mobile_normal_driver __pci_driver = {
 220        .ops    = &sata_ops,
 221        .vendor = PCI_VENDOR_ID_INTEL,
 222        .device = 0x27c4,
 223};
 224
 225
 226/* NOTE: Any of the below are not properly supported yet. */
 227
 228/* Desktop AHCI Mode */
 229/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
 230static const struct pci_driver i82801gx_sata_ahci_driver __pci_driver = {
 231        .ops    = &sata_ops,
 232        .vendor = PCI_VENDOR_ID_INTEL,
 233        .device = 0x27c1,
 234};
 235
 236/* Desktop RAID mode */
 237/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
 238static const struct pci_driver i82801gx_sata_raid_driver __pci_driver = {
 239        .ops    = &sata_ops,
 240        .vendor = PCI_VENDOR_ID_INTEL,
 241        .device = 0x27c3,
 242};
 243
 244/* Mobile AHCI Mode */
 245/* 82801GBM/GHM (ICH7-M/ICH7-M DH) */
 246static const struct pci_driver i82801gx_sata_mobile_ahci_driver __pci_driver = {
 247        .ops    = &sata_ops,
 248        .vendor = PCI_VENDOR_ID_INTEL,
 249        .device = 0x27c5,
 250};
 251
 252/* ICH7M DH Raid Mode */
 253/* 82801GHM (ICH7-M DH) */
 254static const struct pci_driver i82801gx_sata_ich7dh_raid_driver __pci_driver = {
 255        .ops    = &sata_ops,
 256        .vendor = PCI_VENDOR_ID_INTEL,
 257        .device = 0x27c6,
 258};
 259
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.