coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
sata.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
7 #include <device/pci_ids.h>
8 #include "chip.h"
9 #include "i82801gx.h"
10 #include "sata.h"
11 
12 static u8 get_ich7_sata_ports(void)
13 {
14  struct device *lpc;
15 
16  lpc = pcidev_on_root(31, 0);
17 
18  switch (pci_read_config16(lpc, PCI_DEVICE_ID)) {
19  case 0x27b0:
20  case 0x27b8:
21  return 0xf;
22  case 0x27b9:
23  case 0x27bd:
24  return 0x5;
25  case 0x27bc:
26  return 0x3;
27  default:
28  printk(BIOS_ERR, "i82801gx_sata: error: cannot determine port config\n");
29  return 0;
30  }
31 }
32 
33 void sata_enable(struct device *dev)
34 {
35  /* Get the chip configuration */
37 
38  if (config->sata_mode == SATA_MODE_AHCI) {
39  /* Check if the southbridge supports AHCI */
40  struct device *lpc_dev = pcidev_on_root(31, 0);
41  if (!lpc_dev) {
42  /* According to the PCI spec function 0 on a bus:device
43  needs to be active for other functions to be enabled.
44  Since SATA is on the same bus:device as the LPC
45  bridge, it makes little sense to continue. */
46  die("Couldn't find the LPC device!\n");
47  }
48 
49  const bool ahci_supported = !(pci_read_config32(lpc_dev, FDVCT)
51 
52  if (!ahci_supported) {
53  /* Fallback to IDE PLAIN for sata for the rest of the initialization */
54  config->sata_mode = SATA_MODE_IDE_PLAIN;
55  printk(BIOS_DEBUG, "AHCI not supported, falling back to plain mode.\n");
56  }
57 
58  }
59 
60  if (config->sata_mode == SATA_MODE_AHCI) {
61  /* Set map to ahci */
62  pci_update_config8(dev, SATA_MAP, (u8)~0xc3, 0x40);
63  } else {
64  /* Set map to ide */
65  pci_and_config8(dev, SATA_MAP, (u8)~0xc3);
66  }
67  /* At this point, the new pci id will appear on the bus */
68 }
69 
70 static void sata_init(struct device *dev)
71 {
72  u32 reg32;
73  u8 ports;
74 
75  /* Get the chip configuration */
77 
78  printk(BIOS_DEBUG, "i82801gx_sata: initializing...\n");
79 
80  if (config == NULL) {
81  printk(BIOS_ERR, "i82801gx_sata: error: device not in devicetree.cb!\n");
82  return;
83  }
84 
85  /* Get ICH7 SATA port config */
86  ports = get_ich7_sata_ports();
87 
88  /* Enable BARs */
91 
92  switch (config->sata_mode) {
94  printk(BIOS_DEBUG, "SATA controller in combined mode.\n");
95  /* No AHCI: clear AHCI base */
97 
98  /* And without AHCI BAR no memory decoding */
100 
101  pci_write_config8(dev, 0x09, 0x80);
102 
103  /* Set timings */
109 
110  /* Sync DMA */
112  pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
113 
114  /* Set IDE I/O Configuration */
116  pci_write_config32(dev, IDE_CONFIG, reg32);
117 
118  /* Combine IDE - SATA configuration */
119  pci_write_config8(dev, SATA_MAP, 0x02);
120 
121  /* Restrict ports - 0 and 2 only available */
122  ports &= 0x5;
123  break;
124  case SATA_MODE_AHCI:
125  printk(BIOS_DEBUG, "SATA controller in AHCI mode.\n");
126  /* Allow both Legacy and Native mode */
127  pci_write_config8(dev, 0x09, 0x8f);
128 
129  /* Set Interrupt Line */
130  /* Interrupt Pin is set by D31IP.PIP */
131  pci_write_config8(dev, INTR_LN, 0x0a);
132 
133  struct resource *ahci_res = probe_resource(dev, PCI_BASE_ADDRESS_5);
134  if (ahci_res != NULL)
135  /* write AHCI GHC_PI register */
136  write32(res2mmio(ahci_res, 0xc, 0), config->sata_ports_implemented);
137  break;
138  default:
139  case SATA_MODE_IDE_PLAIN:
140  printk(BIOS_DEBUG, "SATA controller in plain mode.\n");
141  /* Set Sata Controller Mode. No Mapping(?) */
142  pci_write_config8(dev, SATA_MAP, 0x00);
143 
144  /* No AHCI: clear AHCI base */
145  pci_write_config32(dev, PCI_BASE_ADDRESS_5, 0x00000000);
146 
147  /* And without AHCI BAR no memory decoding */
149 
150  /* Native mode capable on both primary and secondary (0xa)
151  * or'ed with enabled (0x50) = 0xf
152  */
153  pci_write_config8(dev, 0x09, 0x8f);
154 
155  /* Set Interrupt Line */
156  /* Interrupt Pin is set by D31IP.PIP */
157  pci_write_config8(dev, INTR_LN, 0xff);
158 
159  /* Set timings */
166 
167  /* Sync DMA */
169  pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
170 
171  /* Set IDE I/O Configuration */
173  pci_write_config32(dev, IDE_CONFIG, reg32);
174  break;
175  }
176 
177  /* Set port control */
178  pci_write_config8(dev, SATA_PCS, ports);
179 
180  /* Enable clock gating for unused ports and set initialization reg */
181  pci_write_config32(dev, SATA_IR, SIF3(ports) | SIF2 | SIF1 | SCRE);
182 
183  /* All configurations need this SATA initialization sequence */
184  pci_write_config8(dev, 0xa0, 0x40);
185  pci_write_config8(dev, 0xa6, 0x22);
186  pci_write_config8(dev, 0xa0, 0x78);
187  pci_write_config8(dev, 0xa6, 0x22);
188  pci_write_config8(dev, 0xa0, 0x88);
189  pci_update_config32(dev, 0xa4, 0xc0c0c0c0, 0x1b1b1212);
190  pci_write_config8(dev, 0xa0, 0x8c);
191  pci_update_config32(dev, 0xa4, 0xc0c0ff00, 0x121200aa);
192  pci_write_config8(dev, 0xa0, 0x00);
193 
195 
196  /* Sata Initialization Register */
197  pci_or_config32(dev, SATA_IR, SCRD); // due to some bug
198 }
199 
200 static struct device_operations sata_ops = {
202  .set_resources = pci_dev_set_resources,
203  .enable_resources = pci_dev_enable_resources,
204  .init = sata_init,
205  .enable = i82801gx_enable,
206  .ops_pci = &pci_dev_ops_pci,
207 };
208 
209 static const unsigned short sata_ids[] = {
210  0x27c0, /* Desktop Non-AHCI and Non-RAID Mode: 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
211  0x27c1, /* Desktop AHCI Mode: 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
212  0x27c4, /* Mobile Non-AHCI and Non-RAID Mode: 82801GBM/GHM (ICH7-M/ICH7-M DH) */
213  0x27c5, /* Mobile AHCI Mode: 82801GBM/GHM (ICH7-M/ICH7-M DH) */
214  /* NOTE: Any of the below are not properly supported yet. */
215  0x27c3, /* Desktop RAID mode: 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
216  0x27c6, /* ICH7M DH Raid Mode: 82801GHM (ICH7-M DH) */
217  0
218 };
219 
220 static const struct pci_driver i82801gx_sata_driver __pci_driver = {
221  .ops = &sata_ops,
222  .vendor = PCI_VID_INTEL,
223  .devices = sata_ids,
224 };
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
struct resource * probe_resource(const struct device *dev, unsigned int index)
See if a resource structure already exists for a given index.
Definition: device_util.c:323
void i82801gx_enable(struct device *dev)
Definition: i82801gx.c:54
#define FDVCT
Definition: i82801gx.h:50
#define AHCI_UNSUPPORTED
Definition: i82801gx.h:52
static __always_inline void pci_or_config32(const struct device *dev, u16 reg, u32 ormask)
Definition: pci_ops.h:191
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline void pci_and_config16(const struct device *dev, u16 reg, u16 andmask)
Definition: pci_ops.h:147
static __always_inline void pci_and_config8(const struct device *dev, u16 reg, u8 andmask)
Definition: pci_ops.h:136
static __always_inline void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
Definition: pci_ops.h:120
static __always_inline void pci_update_config8(const struct device *dev, u16 reg, u8 mask, u8 or)
Definition: pci_ops.h:88
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
enum board_config config
Definition: memory.c:448
#define PCI_INTERRUPT_LINE
Definition: pci_def.h:94
#define PCI_COMMAND_IO
Definition: pci_def.h:11
#define PCI_COMMAND_MASTER
Definition: pci_def.h:13
#define PCI_COMMAND_MEMORY
Definition: pci_def.h:12
#define PCI_COMMAND
Definition: pci_def.h:10
#define PCI_DEVICE_ID
Definition: pci_def.h:9
#define PCI_BASE_ADDRESS_5
Definition: pci_def.h:68
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
void pci_dev_read_resources(struct device *dev)
Definition: pci_device.c:534
struct pci_operations pci_dev_ops_pci
Default device operation for PCI devices.
Definition: pci_device.c:911
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
#define PCI_VID_INTEL
Definition: pci_ids.h:2157
static void * res2mmio(const struct resource *res, unsigned long offset, unsigned long mask)
Definition: resource.h:87
#define SATA_PCS
Definition: sata.h:23
#define SATA_MAP
Definition: sata.h:14
#define IDE_SDMA_TIM
Definition: sata.h:60
#define IDE_TIM_PRI
Definition: sata.h:34
#define PCB0
Definition: sata.h:76
#define INTR_LN
Definition: sata.h:33
#define IDE_TIME0
Definition: sata.h:51
#define IDE_PSDE0
Definition: sata.h:58
#define IDE_CONFIG
Definition: sata.h:62
#define PCB1
Definition: sata.h:75
#define IDE_ISP_3_CLOCKS
Definition: sata.h:39
#define IDE_SDMA_CNT
Definition: sata.h:54
#define SIG_MODE_PRI_NORMAL
Definition: sata.h:66
#define IDE_SITRE
Definition: sata.h:36
#define IDE_ISP_5_CLOCKS
Definition: sata.h:37
#define IDE_RCT_1_CLOCKS
Definition: sata.h:43
#define IDE_TIM_SEC
Definition: sata.h:52
#define IDE_IE0
Definition: sata.h:50
#define IDE_SSDE0
Definition: sata.h:56
#define IDE_DECODE_ENABLE
Definition: sata.h:35
#define IDE_RCT_4_CLOCKS
Definition: sata.h:40
#define FAST_PCB0
Definition: sata.h:72
#define FAST_PCB1
Definition: sata.h:71
#define IDE_PPE0
Definition: sata.h:49
@ SATA_MODE_IDE_LEGACY_COMBINED
Definition: chip.h:10
@ SATA_MODE_IDE_PLAIN
Definition: chip.h:11
@ SATA_MODE_AHCI
Definition: chip.h:9
static void sata_init(struct device *dev)
Definition: sata.c:70
void sata_enable(struct device *dev)
Definition: sata.c:33
static struct device_operations sata_ops
Definition: sata.c:200
static const struct pci_driver i82801gx_sata_driver __pci_driver
Definition: sata.c:220
static const unsigned short sata_ids[]
Definition: sata.c:209
static u8 get_ich7_sata_ports(void)
Definition: sata.c:12
#define SIF2
Definition: sata.h:10
#define SIF1
Definition: sata.h:9
#define SIF3(ports)
Definition: sata.h:11
#define SCRD
Definition: sata.h:13
#define SATA_IR
Definition: sata.h:8
#define SCRE
Definition: sata.h:12
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
DEVTREE_CONST void * chip_info
Definition: device.h:164