blob: bca02515d28404488b7f83064025ab0403a5e30b [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Stefan Reinauerdebb11f2008-10-29 04:46:52 +00002
3#include <console/console.h>
4#include <device/device.h>
5#include <device/pci.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02006#include <device/pci_ops.h>
Stefan Reinauerdebb11f2008-10-29 04:46:52 +00007#include <device/pci_ids.h>
Arthur Heymans742df5a2019-06-03 16:24:41 +02008#include "chip.h"
Stefan Reinauerdebb11f2008-10-29 04:46:52 +00009#include "i82801gx.h"
Damien Zammit647e3852016-01-15 13:44:53 +110010#include "sata.h"
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000011
12typedef struct southbridge_intel_i82801gx_config config_t;
13
Damien Zammit647e3852016-01-15 13:44:53 +110014static u8 get_ich7_sata_ports(void)
15{
16 struct device *lpc;
17
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030018 lpc = pcidev_on_root(31, 0);
Damien Zammit647e3852016-01-15 13:44:53 +110019
20 switch (pci_read_config16(lpc, PCI_DEVICE_ID)) {
21 case 0x27b0:
22 case 0x27b8:
23 return 0xf;
24 case 0x27b9:
25 case 0x27bd:
26 return 0x5;
27 case 0x27bc:
28 return 0x3;
29 default:
Elyes HAOUAS92646ea2020-04-04 13:43:03 +020030 printk(BIOS_ERR, "i82801gx_sata: error: cannot determine port config\n");
Damien Zammit647e3852016-01-15 13:44:53 +110031 return 0;
32 }
33}
34
35void sata_enable(struct device *dev)
36{
37 /* Get the chip configuration */
Arthur Heymans5eb81be2019-01-10 23:13:11 +010038 struct southbridge_intel_i82801gx_config *config = dev->chip_info;
Damien Zammit647e3852016-01-15 13:44:53 +110039
Arthur Heymans5eb81be2019-01-10 23:13:11 +010040 if (config->sata_mode == SATA_MODE_AHCI) {
41 /* Check if the southbridge supports AHCI */
42 struct device *lpc_dev = pcidev_on_root(31, 0);
43 if (!lpc_dev) {
44 /* According to the PCI spec function 0 on a bus:device
45 needs to be active for other functions to be enabled.
46 Since SATA is on the same bus:device as the LPC
47 bridge, it makes little sense to continue. */
48 die("Couldn't find the LPC device!\n");
49 }
50
51 const bool ahci_supported = !(pci_read_config32(lpc_dev, FDVCT)
52 & AHCI_UNSUPPORTED);
53
54 if (!ahci_supported) {
Elyes HAOUAS92646ea2020-04-04 13:43:03 +020055 /* Fallback to IDE PLAIN for sata for the rest of the initialization */
Arthur Heymans5eb81be2019-01-10 23:13:11 +010056 config->sata_mode = SATA_MODE_IDE_PLAIN;
Elyes HAOUAS92646ea2020-04-04 13:43:03 +020057 printk(BIOS_DEBUG, "AHCI not supported, falling back to plain mode.\n");
Arthur Heymans5eb81be2019-01-10 23:13:11 +010058 }
59
Damien Zammit647e3852016-01-15 13:44:53 +110060 }
61
Arthur Heymans5eb81be2019-01-10 23:13:11 +010062 if (config->sata_mode == SATA_MODE_AHCI) {
63 /* Set map to ahci */
64 pci_write_config8(dev, SATA_MAP,
Elyes HAOUAS92646ea2020-04-04 13:43:03 +020065 (pci_read_config8(dev, SATA_MAP) & ~0xc3) | 0x40);
Arthur Heymans5eb81be2019-01-10 23:13:11 +010066 } else {
67 /* Set map to ide */
Elyes HAOUAS92646ea2020-04-04 13:43:03 +020068 pci_write_config8(dev, SATA_MAP, pci_read_config8(dev, SATA_MAP) & ~0xc3);
Arthur Heymans5eb81be2019-01-10 23:13:11 +010069 }
Damien Zammit647e3852016-01-15 13:44:53 +110070 /* At this point, the new pci id will appear on the bus */
71}
72
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000073static void sata_init(struct device *dev)
74{
75 u32 reg32;
Stefan Reinauera8e11682009-03-11 14:54:18 +000076 u16 reg16;
Damien Zammit647e3852016-01-15 13:44:53 +110077 u8 ports;
Sven Schnelleb2f173e2011-10-27 13:05:40 +020078
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000079 /* Get the chip configuration */
80 config_t *config = dev->chip_info;
81
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000082 printk(BIOS_DEBUG, "i82801gx_sata: initializing...\n");
Stefan Reinauera8e11682009-03-11 14:54:18 +000083
Stefan Reinauer573f7d42009-07-21 21:50:34 +000084 if (config == NULL) {
Uwe Hermann607614d2010-11-18 20:12:13 +000085 printk(BIOS_ERR, "i82801gx_sata: error: device not in devicetree.cb!\n");
Stefan Reinauer573f7d42009-07-21 21:50:34 +000086 return;
87 }
Stefan Reinauera8e11682009-03-11 14:54:18 +000088
Damien Zammit647e3852016-01-15 13:44:53 +110089 /* Get ICH7 SATA port config */
90 ports = get_ich7_sata_ports();
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000091
92 /* Enable BARs */
Stefan Reinauera8e11682009-03-11 14:54:18 +000093 pci_write_config16(dev, PCI_COMMAND, 0x0007);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000094
Arthur Heymans5eb81be2019-01-10 23:13:11 +010095 switch (config->sata_mode) {
96 case SATA_MODE_IDE_LEGACY_COMBINED:
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000097 printk(BIOS_DEBUG, "SATA controller in combined mode.\n");
Stefan Reinauera8e11682009-03-11 14:54:18 +000098 /* No AHCI: clear AHCI base */
Petr Cvekc49869b2019-10-01 04:01:21 +020099 pci_write_config32(dev, PCI_BASE_ADDRESS_5, 0x00000000);
Stefan Reinauera8e11682009-03-11 14:54:18 +0000100 /* And without AHCI BAR no memory decoding */
101 reg16 = pci_read_config16(dev, PCI_COMMAND);
102 reg16 &= ~PCI_COMMAND_MEMORY;
103 pci_write_config16(dev, PCI_COMMAND, reg16);
104
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000105 pci_write_config8(dev, 0x09, 0x80);
106
107 /* Set timings */
Stefan Reinauer573f7d42009-07-21 21:50:34 +0000108 pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
109 IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
110 pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
111 IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
112 IDE_PPE0 | IDE_IE0 | IDE_TIME0);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000113
114 /* Sync DMA */
Stefan Reinauer573f7d42009-07-21 21:50:34 +0000115 pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
116 pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000117
Stefan Reinauera8e11682009-03-11 14:54:18 +0000118 /* Set IDE I/O Configuration */
Stefan Reinaueraca6ec62009-10-26 17:12:21 +0000119 reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
Stefan Reinauera8e11682009-03-11 14:54:18 +0000120 pci_write_config32(dev, IDE_CONFIG, reg32);
121
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000122 /* Combine IDE - SATA configuration */
Damien Zammit647e3852016-01-15 13:44:53 +1100123 pci_write_config8(dev, SATA_MAP, 0x02);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000124
Damien Zammit1533f132016-01-16 02:52:53 +1100125 /* Restrict ports - 0 and 2 only available */
126 ports &= 0x5;
Arthur Heymans5eb81be2019-01-10 23:13:11 +0100127 break;
128 case SATA_MODE_AHCI:
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000129 printk(BIOS_DEBUG, "SATA controller in AHCI mode.\n");
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000130 /* Allow both Legacy and Native mode */
131 pci_write_config8(dev, 0x09, 0x8f);
132
133 /* Set Interrupt Line */
134 /* Interrupt Pin is set by D31IP.PIP */
135 pci_write_config8(dev, INTR_LN, 0x0a);
136
Petr Cvekc49869b2019-10-01 04:01:21 +0200137 struct resource *ahci_res = find_resource(dev, PCI_BASE_ADDRESS_5);
138 if (ahci_res != NULL)
139 /* write AHCI GHC_PI register */
Elyes HAOUAS92646ea2020-04-04 13:43:03 +0200140 write32(res2mmio(ahci_res, 0xc, 0), config->sata_ports_implemented);
Arthur Heymans5eb81be2019-01-10 23:13:11 +0100141 break;
142 default:
143 case SATA_MODE_IDE_PLAIN:
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000144 printk(BIOS_DEBUG, "SATA controller in plain mode.\n");
Stefan Reinauera8e11682009-03-11 14:54:18 +0000145 /* Set Sata Controller Mode. No Mapping(?) */
Damien Zammit647e3852016-01-15 13:44:53 +1100146 pci_write_config8(dev, SATA_MAP, 0x00);
Stefan Reinauera8e11682009-03-11 14:54:18 +0000147
148 /* No AHCI: clear AHCI base */
Petr Cvekc49869b2019-10-01 04:01:21 +0200149 pci_write_config32(dev, PCI_BASE_ADDRESS_5, 0x00000000);
Stefan Reinauera8e11682009-03-11 14:54:18 +0000150
151 /* And without AHCI BAR no memory decoding */
152 reg16 = pci_read_config16(dev, PCI_COMMAND);
153 reg16 &= ~PCI_COMMAND_MEMORY;
154 pci_write_config16(dev, PCI_COMMAND, reg16);
155
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000156 /* Native mode capable on both primary and secondary (0xa)
157 * or'ed with enabled (0x50) = 0xf
158 */
159 pci_write_config8(dev, 0x09, 0x8f);
160
161 /* Set Interrupt Line */
162 /* Interrupt Pin is set by D31IP.PIP */
163 pci_write_config8(dev, INTR_LN, 0xff);
Stefan Reinauer109ab312009-08-12 16:08:05 +0000164
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000165 /* Set timings */
Stefan Reinauer573f7d42009-07-21 21:50:34 +0000166 pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
167 IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
168 IDE_PPE0 | IDE_IE0 | IDE_TIME0);
169 pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
Stefan Reinauer109ab312009-08-12 16:08:05 +0000170 IDE_SITRE | IDE_ISP_3_CLOCKS |
Stefan Reinauer573f7d42009-07-21 21:50:34 +0000171 IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
Stefan Reinauer109ab312009-08-12 16:08:05 +0000172
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000173 /* Sync DMA */
Stefan Reinauer573f7d42009-07-21 21:50:34 +0000174 pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
175 pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
Stefan Reinauer109ab312009-08-12 16:08:05 +0000176
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000177 /* Set IDE I/O Configuration */
Stefan Reinaueraca6ec62009-10-26 17:12:21 +0000178 reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000179 pci_write_config32(dev, IDE_CONFIG, reg32);
Arthur Heymans5eb81be2019-01-10 23:13:11 +0100180 break;
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000181 }
182
Damien Zammit1533f132016-01-16 02:52:53 +1100183 /* Set port control */
184 pci_write_config8(dev, SATA_PCS, ports);
185
Damien Zammit647e3852016-01-15 13:44:53 +1100186 /* Enable clock gating for unused ports and set initialization reg */
187 pci_write_config32(dev, SATA_IR, SIF3(ports) | SIF2 | SIF1 | SCRE);
188
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000189 /* All configurations need this SATA initialization sequence */
190 pci_write_config8(dev, 0xa0, 0x40);
191 pci_write_config8(dev, 0xa6, 0x22);
192 pci_write_config8(dev, 0xa0, 0x78);
193 pci_write_config8(dev, 0xa6, 0x22);
194 pci_write_config8(dev, 0xa0, 0x88);
195 reg32 = pci_read_config32(dev, 0xa4);
196 reg32 &= 0xc0c0c0c0;
197 reg32 |= 0x1b1b1212;
198 pci_write_config32(dev, 0xa4, reg32);
199 pci_write_config8(dev, 0xa0, 0x8c);
200 reg32 = pci_read_config32(dev, 0xa4);
201 reg32 &= 0xc0c0ff00;
202 reg32 |= 0x121200aa;
203 pci_write_config32(dev, 0xa4, reg32);
204 pci_write_config8(dev, 0xa0, 0x00);
Stefan Reinauer54309d62009-01-20 22:53:10 +0000205
206 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Stefan Reinauera8e11682009-03-11 14:54:18 +0000207
208 /* Sata Initialization Register */
Damien Zammit647e3852016-01-15 13:44:53 +1100209 reg32 = pci_read_config32(dev, SATA_IR);
210 reg32 |= SCRD; // due to some bug
211 pci_write_config32(dev, SATA_IR, reg32);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000212}
213
Stefan Reinauera8e11682009-03-11 14:54:18 +0000214static struct pci_operations sata_pci_ops = {
Elyes HAOUAS92646ea2020-04-04 13:43:03 +0200215 .set_subsystem = pci_dev_set_subsystem,
Stefan Reinauera8e11682009-03-11 14:54:18 +0000216};
217
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000218static struct device_operations sata_ops = {
219 .read_resources = pci_dev_read_resources,
220 .set_resources = pci_dev_set_resources,
221 .enable_resources = pci_dev_enable_resources,
222 .init = sata_init,
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000223 .enable = i82801gx_enable,
Stefan Reinauera8e11682009-03-11 14:54:18 +0000224 .ops_pci = &sata_pci_ops,
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000225};
226
Patrick Georgiefff7332012-07-26 19:48:23 +0200227static const unsigned short sata_ids[] = {
228 0x27c0, /* Desktop Non-AHCI and Non-RAID Mode: 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
Patrick Georgiefff7332012-07-26 19:48:23 +0200229 0x27c1, /* Desktop AHCI Mode: 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
Damien Zammit647e3852016-01-15 13:44:53 +1100230 0x27c4, /* Mobile Non-AHCI and Non-RAID Mode: 82801GBM/GHM (ICH7-M/ICH7-M DH) */
Patrick Georgiefff7332012-07-26 19:48:23 +0200231 0x27c5, /* Mobile AHCI Mode: 82801GBM/GHM (ICH7-M/ICH7-M DH) */
Damien Zammit647e3852016-01-15 13:44:53 +1100232 /* NOTE: Any of the below are not properly supported yet. */
233 0x27c3, /* Desktop RAID mode: 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
Patrick Georgiefff7332012-07-26 19:48:23 +0200234 0x27c6, /* ICH7M DH Raid Mode: 82801GHM (ICH7-M DH) */
235 0
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000236};
237
Patrick Georgiefff7332012-07-26 19:48:23 +0200238static const struct pci_driver i82801gx_sata_driver __pci_driver = {
Arthur Heymans3f111b02017-03-09 12:02:52 +0100239 .ops = &sata_ops,
240 .vendor = PCI_VENDOR_ID_INTEL,
241 .devices = sata_ids,
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000242};