blob: 73a7d82bd31460938a0971c43d3439073d1c374a [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Arthur Heymans7b9c1392017-04-09 20:40:39 +02002
3#include <arch/io.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02005#include <device/pci_ops.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +02006#include <console/console.h>
7#include <device/device.h>
8#include <device/pci.h>
9#include <device/pci_ids.h>
Kyösti Mälkkicbf95712020-01-05 08:05:45 +020010#include <option.h>
Elyes HAOUASab89edb2019-05-15 21:10:44 +020011#include <types.h>
12
Kyösti Mälkki12b121c2019-08-18 16:33:39 +030013#include "chip.h"
Elyes HAOUASab89edb2019-05-15 21:10:44 +020014#include "i82801jx.h"
Arthur Heymans7b9c1392017-04-09 20:40:39 +020015
Arthur Heymans349e0852017-04-09 20:48:37 +020016typedef struct southbridge_intel_i82801jx_config config_t;
Arthur Heymans7b9c1392017-04-09 20:40:39 +020017
18static void sata_enable_ahci_mmap(struct device *const dev, const u8 port_map,
19 const int is_mobile)
20{
21 int i;
22 u32 reg32;
23
24 /* Initialize AHCI memory-mapped space */
25 u8 *abar = (u8 *)pci_read_config32(dev, PCI_BASE_ADDRESS_5);
26 printk(BIOS_DEBUG, "ABAR: %p\n", abar);
27
28 /* Set AHCI access mode.
29 No other ABAR registers should be accessed before this. */
30 reg32 = read32(abar + 0x04);
31 reg32 |= 1 << 31;
32 write32(abar + 0x04, reg32);
33
34 /* CAP (HBA Capabilities) : enable power management */
35 reg32 = read32(abar + 0x00);
36 /* CCCS must be set. */
37 reg32 |= 0x0c006080; /* set CCCS+PSC+SSC+SALP+SSS */
38 reg32 &= ~0x00020060; /* clear SXS+EMS+PMS */
39 write32(abar + 0x00, reg32);
40
41 /* PI (Ports implemented) */
42 write32(abar + 0x0c, port_map);
43 /* PCH code reads back twice, do we need it, too? */
44 (void) read32(abar + 0x0c); /* Read back 1 */
45 (void) read32(abar + 0x0c); /* Read back 2 */
46
47 /* VSP (Vendor Specific Register) */
48 reg32 = read32(abar + 0xa0);
49 reg32 &= ~0x00000001; /* clear SLPD */
50 write32(abar + 0xa0, reg32);
51
52 /* Lock R/WO bits in Port command registers. */
53 for (i = 0; i < 6; ++i) {
54 if (((i == 2) || (i == 3)) && is_mobile)
55 continue;
56 u8 *addr = abar + 0x118 + (i * 0x80);
57 write32(addr, read32(addr));
58 }
59}
60
61static void sata_program_indexed(struct device *const dev, const int is_mobile)
62{
63 u32 reg32;
64
65 pci_write_config8(dev, D31F2_SIDX, 0x18);
66 reg32 = pci_read_config32(dev, D31F2_SDAT);
67 reg32 &= ~((7 << 6) | (7 << 3) | (7 << 0));
68 reg32 |= (3 << 3) | (3 << 0);
69 pci_write_config32(dev, D31F2_SDAT, reg32);
70
71 pci_write_config8(dev, D31F2_SIDX, 0x28);
72 pci_write_config32(dev, D31F2_SDAT, 0x00cc2080);
73
74 pci_write_config8(dev, D31F2_SIDX, 0x40);
75 pci_write_config8(dev, D31F2_SDAT + 2, 0x22);
76
77 pci_write_config8(dev, D31F2_SIDX, 0x78);
78 pci_write_config8(dev, D31F2_SDAT + 2, 0x22);
79
80 if (!is_mobile) {
81 pci_write_config8(dev, D31F2_SIDX, 0x84);
82 reg32 = pci_read_config32(dev, D31F2_SDAT);
83 reg32 &= ~((7 << 3) | (7 << 0));
84 reg32 |= (3 << 3) | (3 << 0);
85 pci_write_config32(dev, D31F2_SDAT, reg32);
86 }
87
88 pci_write_config8(dev, D31F2_SIDX, 0x88);
89 reg32 = pci_read_config32(dev, D31F2_SDAT);
90 if (!is_mobile)
91 reg32 &= ~((7 << 27) | (7 << 24) | (7 << 11) | (7 << 8));
92 reg32 &= ~((7 << 19) | (7 << 16) | (7 << 3) | (7 << 0));
93 if (!is_mobile)
94 reg32 |= (4 << 27) | (4 << 24) | (2 << 11) | (2 << 8);
95 reg32 |= (4 << 19) | (4 << 16) | (2 << 3) | (2 << 0);
96 pci_write_config32(dev, D31F2_SDAT, reg32);
97
98 pci_write_config8(dev, D31F2_SIDX, 0x8c);
99 reg32 = pci_read_config32(dev, D31F2_SDAT);
100 if (!is_mobile)
101 reg32 &= ~((7 << 27) | (7 << 24));
102 reg32 &= ~((7 << 19) | (7 << 16) | 0xffff);
103 if (!is_mobile)
104 reg32 |= (2 << 27) | (2 << 24);
105 reg32 |= (2 << 19) | (2 << 16) | 0x00aa;
106 pci_write_config32(dev, D31F2_SDAT, reg32);
107
108 pci_write_config8(dev, D31F2_SIDX, 0x94);
109 pci_write_config32(dev, D31F2_SDAT, 0x00000022);
110
111 pci_write_config8(dev, D31F2_SIDX, 0xa0);
112 reg32 = pci_read_config32(dev, D31F2_SDAT);
113 reg32 &= ~((7 << 3) | (7 << 0));
114 reg32 |= (3 << 3) | (3 << 0);
115 pci_write_config32(dev, D31F2_SDAT, reg32);
116
117 pci_write_config8(dev, D31F2_SIDX, 0xa8);
118 reg32 = pci_read_config32(dev, D31F2_SDAT);
119 reg32 &= ~((7 << 19) | (7 << 16) | (7 << 3) | (7 << 0));
120 reg32 |= (4 << 19) | (4 << 16) | (2 << 3) | (2 << 0);
121 pci_write_config32(dev, D31F2_SDAT, reg32);
122
123 pci_write_config8(dev, D31F2_SIDX, 0xac);
124 reg32 = pci_read_config32(dev, D31F2_SDAT);
125 reg32 &= ~((7 << 19) | (7 << 16) | 0xffff);
126 reg32 |= (2 << 19) | (2 << 16) | 0x000a;
127 pci_write_config32(dev, D31F2_SDAT, reg32);
128}
129
130static void sata_init(struct device *const dev)
131{
132 u16 reg16;
133
134 /* Get the chip configuration */
135 const config_t *const config = dev->chip_info;
136
137 const u16 devid = pci_read_config16(dev, PCI_DEVICE_ID);
138 const int is_mobile = (devid == 0x2928) || (devid == 0x2929);
139 u8 sata_mode;
140
Arthur Heymans349e0852017-04-09 20:48:37 +0200141 printk(BIOS_DEBUG, "i82801jx_sata: initializing...\n");
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200142
143 if (config == NULL) {
Arthur Heymans349e0852017-04-09 20:48:37 +0200144 printk(BIOS_ERR, "i82801jx_sata: error: "
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200145 "device not in devicetree.cb!\n");
146 return;
147 }
148
149 if (get_option(&sata_mode, "sata_mode") != CB_SUCCESS)
150 /* Default to AHCI */
151 sata_mode = 0;
152
153 /*
154 * TODO: In contrast to ICH7 and PCH code we don't set
155 * timings, dma and IDE-I/O settings here. Looks like they
156 * became obsolete with the fading of real IDE ports.
157 * Maybe we can safely remove those settings from PCH code and
158 * even ICH7 code if it doesn't use the feature to combine the
159 * IDE and SATA controllers.
160 */
161
162 pci_write_config16(dev, PCI_COMMAND,
163 PCI_COMMAND_MASTER |
164 PCI_COMMAND_MEMORY | /* read-only in IDE modes */
165 PCI_COMMAND_IO);
166 if (sata_mode != 0)
167 /* No AHCI: clear AHCI base */
168 pci_write_config32(dev, PCI_BASE_ADDRESS_5, 0x00000000);
169
170 if (sata_mode == 0) {
171 printk(BIOS_DEBUG, "SATA controller in AHCI mode.\n");
172 } else {
173 printk(BIOS_DEBUG, "SATA controller in native mode.\n");
174
175 /* Enable native mode on both primary and secondary. */
176 pci_write_config8(dev, PCI_CLASS_PROG, 0x8f);
177 }
178
179 /* Looks like we should only enable decoding here. */
180 pci_write_config16(dev, D31F2_IDE_TIM_PRI, (1 << 15));
181 pci_write_config16(dev, D31F2_IDE_TIM_SEC, (1 << 15));
182
183 /* Port enable. For AHCI, it's managed in memory mapped space. */
184 reg16 = pci_read_config16(dev, 0x92);
185 reg16 &= ~0x3f;
186 reg16 |= (1 << 15) | ((sata_mode == 0) ? 0x3f : config->sata_port_map);
187 pci_write_config16(dev, 0x92, reg16);
188
189 /* SATA clock settings */
190 u32 sclkcg = 0;
191 if (config->sata_clock_request &&
192 !(inb(DEFAULT_GPIOBASE + 0x30) & (1 << (35 - 32))))
193 sclkcg |= 1 << 30; /* Enable SATA clock request. */
194 /* Disable unused ports. */
195 sclkcg |= ((~config->sata_port_map) & 0x3f) << 24;
196 /* Must be programmed. */
197 sclkcg |= 0x193;
198 pci_write_config32(dev, 0x94, sclkcg);
199
200 if (is_mobile && config->sata_traffic_monitor) {
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300201 struct device *const lpc_dev = pcidev_on_root(0x1f, 0);
Angel Pons2048cb42020-06-08 02:09:33 +0200202 if (((pci_read_config8(lpc_dev, D31F0_CxSTATE_CNF) >> 3) & 3) == 3) {
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200203 u8 reg8 = pci_read_config8(dev, 0x9c);
204 reg8 &= ~(0x1f << 2);
205 reg8 |= 3 << 2;
206 pci_write_config8(dev, 0x9c, reg8);
207 }
208 }
209
210 if (sata_mode == 0)
211 sata_enable_ahci_mmap(dev, config->sata_port_map, is_mobile);
212
213 sata_program_indexed(dev, is_mobile);
214}
215
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200216static void sata_enable(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200217{
218 /* Get the chip configuration */
219 const config_t *const config = dev->chip_info;
220
221 u16 map = 0;
222 u8 sata_mode;
223
224 if (!config)
225 return;
226
227 if (get_option(&sata_mode, "sata_mode") != CB_SUCCESS)
228 /* Default to AHCI */
229 sata_mode = 0;
230
231 /*
232 * Set SATA controller mode early so the resource allocator can
233 * properly assign IO/Memory resources for the controller.
234 */
235 if (sata_mode == 0)
236 map = 0x0040 | 0x0020; /* SATA mode + all ports on D31:F2 */
237
238 map |= (config->sata_port_map ^ 0x3f) << 8;
239
240 pci_write_config16(dev, 0x90, map);
241}
242
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200243static struct device_operations sata_ops = {
244 .read_resources = pci_dev_read_resources,
245 .set_resources = pci_dev_set_resources,
246 .enable_resources = pci_dev_enable_resources,
247 .init = sata_init,
248 .enable = sata_enable,
Angel Pons1fc0edd2020-05-31 00:03:28 +0200249 .ops_pci = &pci_dev_ops_pci,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200250};
251
252static const unsigned short pci_device_ids[] = {
Arthur Heymans349e0852017-04-09 20:48:37 +0200253 0x3a00,
254 0x3a02,
255 0x3a05,
256 0x3a06,
257 0x3a20,
258 0x3a22,
259 0x3a25,
260 0x3a26,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200261 0,
262};
263
264static const struct pci_driver pch_sata __pci_driver = {
265 .ops = &sata_ops,
266 .vendor = PCI_VENDOR_ID_INTEL,
267 .devices = pci_device_ids,
268};