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 <device/mmio.h>
4 #include <device/pci_ops.h>
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <option.h>
10 #include <acpi/acpi_sata.h>
11 #include <types.h>
12 
13 #include "chip.h"
14 #include "pch.h"
15 
16 static inline u32 sir_read(struct device *dev, int idx)
17 {
18  pci_write_config32(dev, SATA_SIRI, idx);
19  return pci_read_config32(dev, SATA_SIRD);
20 }
21 
22 static inline void sir_write(struct device *dev, int idx, u32 value)
23 {
24  pci_write_config32(dev, SATA_SIRI, idx);
26 }
27 
28 static void sata_init(struct device *dev)
29 {
30  u32 reg32;
31  u16 reg16;
32  /* Get the chip configuration */
33  const struct southbridge_intel_ibexpeak_config *config = dev->chip_info;
34 
35  printk(BIOS_DEBUG, "SATA: Initializing...\n");
36 
37  if (config == NULL) {
38  printk(BIOS_ERR, "SATA: ERROR: Device not in devicetree.cb!\n");
39  return;
40  }
41 
42  /* Default to AHCI */
43  u8 sata_mode = get_uint_option("sata_mode", 0);
44 
45  /* SATA configuration */
46 
47  /* Enable BARs */
50 
51  if (sata_mode == 0) {
52  /* AHCI */
53  u32 *abar;
54 
55  printk(BIOS_DEBUG, "SATA: Controller in AHCI mode.\n");
56 
57  /* Set Interrupt Line */
58  /* Interrupt Pin is set by D31IP.PIP */
59  pci_write_config8(dev, INTR_LN, 0x0b);
60 
61  /* Set timings */
64 
65  /* for AHCI, Port Enable is managed in memory mapped space */
66  reg16 = pci_read_config16(dev, 0x92);
67  reg16 &= ~0x3f; /* 6 ports SKU + ORM */
68  reg16 |= 0x8100 | config->sata_port_map;
69  pci_write_config16(dev, 0x92, reg16);
70 
71  /* SATA Initialization register */
72  pci_write_config32(dev, 0x94,
73  ((config->
74  sata_port_map ^ 0x3f) << 24) | 0x183 |
75  0x40000000);
76  pci_write_config32(dev, 0x98, 0x00590200);
77 
78  /* Initialize AHCI memory-mapped space */
80  printk(BIOS_DEBUG, "ABAR: %p\n", abar);
81  /* CAP (HBA Capabilities) : enable power management */
82  reg32 = read32(abar + 0x00);
83  reg32 |= 0x0c006000; // set PSC+SSC+SALP+SSS
84  reg32 &= ~0x00020060; // clear SXS+EMS+PMS
85  /* Set ISS, if available */
86  if (config->sata_interface_speed_support) {
87  reg32 &= ~0x00f00000;
88  reg32 |= (config->sata_interface_speed_support & 0x03)
89  << 20;
90  }
91  write32(abar + 0x00, reg32);
92  /* PI (Ports implemented) */
93  write32(abar + 0x03, config->sata_port_map);
94  (void)read32(abar + 0x03); /* Read back 1 */
95  (void)read32(abar + 0x03); /* Read back 2 */
96  /* CAP2 (HBA Capabilities Extended) */
97  reg32 = read32(abar + 0x09);
98  reg32 &= ~0x00000002;
99  write32(abar + 0x09, reg32);
100  /* VSP (Vendor Specific Register */
101  reg32 = read32(abar + 0x28);
102  reg32 &= ~0x00000005;
103  write32(abar + 0x28, reg32);
104  } else {
105  /* IDE */
106  printk(BIOS_DEBUG, "SATA: Controller in plain mode.\n");
107 
108  /* No AHCI: clear AHCI base */
109  pci_write_config32(dev, 0x24, 0x00000000);
110 
111  /* And without AHCI BAR no memory decoding */
112  reg16 = pci_read_config16(dev, PCI_COMMAND);
113  reg16 &= ~PCI_COMMAND_MEMORY;
114  pci_write_config16(dev, PCI_COMMAND, reg16);
115 
116  /* Native mode capable on both primary and secondary (0xa)
117  * or'ed with enabled (0x50) = 0xf
118  */
119  pci_write_config8(dev, 0x09, 0x8f);
120 
121  /* Set Interrupt Line */
122  /* Interrupt Pin is set by D31IP.PIP */
123  pci_write_config8(dev, INTR_LN, 0xff);
124 
125  /* Set timings */
128 
129  /* Port enable */
130  reg16 = pci_read_config16(dev, 0x92);
131  reg16 &= ~0x3f;
132  reg16 |= config->sata_port_map;
133  pci_write_config16(dev, 0x92, reg16);
134 
135  /* SATA Initialization register */
136  pci_write_config32(dev, 0x94,
137  ((config->
138  sata_port_map ^ 0x3f) << 24) | 0x183);
139  }
140 
141  /* Additional Programming Requirements */
142  sir_write(dev, 0x04, 0x00000000);
143  sir_write(dev, 0x28, 0x0a000033);
144  reg32 = sir_read(dev, 0x54);
145  reg32 &= 0xff000000;
146  reg32 |= 0x555555;
147  sir_write(dev, 0x54, reg32);
148  sir_write(dev, 0x64, 0xcccccccc);
149  reg32 = sir_read(dev, 0x68);
150  reg32 &= 0xffff0000;
151  reg32 |= 0xcccc;
152  sir_write(dev, 0x68, reg32);
153  reg32 = sir_read(dev, 0x78);
154  reg32 &= 0x0000ffff;
155  reg32 |= 0x88880000;
156  sir_write(dev, 0x78, reg32);
157  sir_write(dev, 0x84, 0x001c7000);
158  sir_write(dev, 0x88, 0x88888888);
159  sir_write(dev, 0xa0, 0x001c7000);
160  // a4
161  sir_write(dev, 0xc4, 0x0c0c0c0c);
162  sir_write(dev, 0xc8, 0x0c0c0c0c);
163  sir_write(dev, 0xd4, 0x10000000);
164 }
165 
166 static void sata_enable(struct device *dev)
167 {
168  /* Get the chip configuration */
169  const struct southbridge_intel_ibexpeak_config *config = dev->chip_info;
170  u16 map = 0;
171 
172  if (!config)
173  return;
174 
175  u8 sata_mode = get_uint_option("sata_mode", 0);
176 
177  /*
178  * Set SATA controller mode early so the resource allocator can
179  * properly assign IO/Memory resources for the controller.
180  */
181  if (sata_mode == 0)
182  map = 0x0060;
183 
184  map |= (config->sata_port_map ^ 0x3f) << 8;
185 
186  pci_write_config16(dev, 0x90, map);
187 }
188 
189 static void sata_fill_ssdt(const struct device *dev)
190 {
191  const struct southbridge_intel_ibexpeak_config *config = dev->chip_info;
192  generate_sata_ssdt_ports("\\_SB_.PCI0.SATA", config->sata_port_map);
193 }
194 
195 static struct device_operations sata_ops = {
197  .set_resources = pci_dev_set_resources,
198  .enable_resources = pci_dev_enable_resources,
199  .init = sata_init,
200  .enable = sata_enable,
201  .acpi_fill_ssdt = sata_fill_ssdt,
202  .ops_pci = &pci_dev_ops_pci,
203 };
204 
205 static const unsigned short pci_device_ids[] = {
209  0
210 };
211 
212 static const struct pci_driver pch_sata __pci_driver = {
213  .ops = &sata_ops,
214  .vendor = PCI_VID_INTEL,
215  .devices = pci_device_ids,
216 };
void generate_sata_ssdt_ports(const char *scope, uint32_t enable_map)
Definition: sata.c:23
pte_t value
Definition: mmu.c:91
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define printk(level,...)
Definition: stdlib.h:16
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
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
unsigned int get_uint_option(const char *name, const unsigned int fallback)
Definition: option.c:116
#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_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
#define PCI_DID_INTEL_IBEXPEAK_MOBILE_SATA_IDE_1
Definition: pci_ids.h:2807
#define PCI_DID_INTEL_IBEXPEAK_MOBILE_SATA_IDE_2
Definition: pci_ids.h:2809
#define PCI_DID_INTEL_IBEXPEAK_MOBILE_SATA_AHCI
Definition: pci_ids.h:2808
#define SATA_SIRI
Definition: sata.h:6
#define SATA_SIRD
Definition: sata.h:7
#define IDE_TIM_PRI
Definition: sata.h:34
#define INTR_LN
Definition: sata.h:33
#define IDE_TIM_SEC
Definition: sata.h:52
#define IDE_DECODE_ENABLE
Definition: sata.h:35
sata_mode
Definition: chip.h:8
void sata_enable(struct device *dev)
Definition: sata.c:33
static const struct pci_driver pch_sata __pci_driver
Definition: sata.c:212
static void sata_init(struct device *dev)
Definition: sata.c:28
static struct device_operations sata_ops
Definition: sata.c:195
static const unsigned short pci_device_ids[]
Definition: sata.c:205
static void sir_write(struct device *dev, int idx, u32 value)
Definition: sata.c:22
static void sata_fill_ssdt(const struct device *dev)
Definition: sata.c:189
static u32 sir_read(struct device *dev, int idx)
Definition: sata.c:16
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint16_t u16
Definition: stdint.h:48
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
typedef void(X86APIP X86EMU_intrFuncs)(int num)