xref: /openbmc/u-boot/arch/x86/cpu/ivybridge/sata.c (revision dffceb4b)
1 /*
2  * From Coreboot
3  * Copyright (C) 2008-2009 coresystems GmbH
4  *
5  * SPDX-License-Identifier:	GPL-2.0
6  */
7 
8 #include <common.h>
9 #include <dm.h>
10 #include <fdtdec.h>
11 #include <asm/io.h>
12 #include <asm/pci.h>
13 #include <asm/arch/pch.h>
14 #include <asm/arch/bd82x6x.h>
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 static inline u32 sir_read(struct udevice *dev, int idx)
19 {
20 	u32 data;
21 
22 	dm_pci_write_config32(dev, SATA_SIRI, idx);
23 	dm_pci_read_config32(dev, SATA_SIRD, &data);
24 
25 	return data;
26 }
27 
28 static inline void sir_write(struct udevice *dev, int idx, u32 value)
29 {
30 	dm_pci_write_config32(dev, SATA_SIRI, idx);
31 	dm_pci_write_config32(dev, SATA_SIRD, value);
32 }
33 
34 static void common_sata_init(struct udevice *dev, unsigned int port_map)
35 {
36 	u32 reg32;
37 	u16 reg16;
38 
39 	/* Set IDE I/O Configuration */
40 	reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
41 	dm_pci_write_config32(dev, IDE_CONFIG, reg32);
42 
43 	/* Port enable */
44 	dm_pci_read_config16(dev, 0x92, &reg16);
45 	reg16 &= ~0x3f;
46 	reg16 |= port_map;
47 	dm_pci_write_config16(dev, 0x92, reg16);
48 
49 	/* SATA Initialization register */
50 	port_map &= 0xff;
51 	dm_pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183);
52 }
53 
54 static void bd82x6x_sata_init(struct udevice *dev, struct udevice *pch)
55 {
56 	unsigned int port_map, speed_support, port_tx;
57 	const void *blob = gd->fdt_blob;
58 	int node = dev->of_offset;
59 	const char *mode;
60 	u32 reg32;
61 	u16 reg16;
62 
63 	debug("SATA: Initializing...\n");
64 
65 	/* SATA configuration */
66 	port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
67 	speed_support = fdtdec_get_int(blob, node,
68 				       "sata_interface_speed_support", 0);
69 
70 	mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
71 	if (!mode || !strcmp(mode, "ahci")) {
72 		u32 abar;
73 
74 		debug("SATA: Controller in AHCI mode\n");
75 
76 		/* Set timings */
77 		dm_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
78 				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
79 				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
80 		dm_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
81 				IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
82 
83 		/* Sync DMA */
84 		dm_pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
85 		dm_pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
86 
87 		common_sata_init(dev, 0x8000 | port_map);
88 
89 		/* Initialize AHCI memory-mapped space */
90 		abar = dm_pci_read_bar32(dev, 5);
91 		debug("ABAR: %08X\n", abar);
92 		/* CAP (HBA Capabilities) : enable power management */
93 		reg32 = readl(abar + 0x00);
94 		reg32 |= 0x0c006000;  /* set PSC+SSC+SALP+SSS */
95 		reg32 &= ~0x00020060; /* clear SXS+EMS+PMS */
96 		/* Set ISS, if available */
97 		if (speed_support) {
98 			reg32 &= ~0x00f00000;
99 			reg32 |= (speed_support & 0x03) << 20;
100 		}
101 		writel(reg32, abar + 0x00);
102 		/* PI (Ports implemented) */
103 		writel(port_map, abar + 0x0c);
104 		(void) readl(abar + 0x0c); /* Read back 1 */
105 		(void) readl(abar + 0x0c); /* Read back 2 */
106 		/* CAP2 (HBA Capabilities Extended)*/
107 		reg32 = readl(abar + 0x24);
108 		reg32 &= ~0x00000002;
109 		writel(reg32, abar + 0x24);
110 		/* VSP (Vendor Specific Register */
111 		reg32 = readl(abar + 0xa0);
112 		reg32 &= ~0x00000005;
113 		writel(reg32, abar + 0xa0);
114 	} else if (!strcmp(mode, "combined")) {
115 		debug("SATA: Controller in combined mode\n");
116 
117 		/* No AHCI: clear AHCI base */
118 		dm_pci_write_bar32(dev, 5, 0x00000000);
119 		/* And without AHCI BAR no memory decoding */
120 		dm_pci_read_config16(dev, PCI_COMMAND, &reg16);
121 		reg16 &= ~PCI_COMMAND_MEMORY;
122 		dm_pci_write_config16(dev, PCI_COMMAND, reg16);
123 
124 		dm_pci_write_config8(dev, 0x09, 0x80);
125 
126 		/* Set timings */
127 		dm_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
128 				IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
129 		dm_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
130 				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
131 				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
132 
133 		/* Sync DMA */
134 		dm_pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
135 		dm_pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
136 
137 		common_sata_init(dev, port_map);
138 	} else {
139 		debug("SATA: Controller in plain-ide mode\n");
140 
141 		/* No AHCI: clear AHCI base */
142 		dm_pci_write_bar32(dev, 5, 0x00000000);
143 
144 		/* And without AHCI BAR no memory decoding */
145 		dm_pci_read_config16(dev, PCI_COMMAND, &reg16);
146 		reg16 &= ~PCI_COMMAND_MEMORY;
147 		dm_pci_write_config16(dev, PCI_COMMAND, reg16);
148 
149 		/*
150 		 * Native mode capable on both primary and secondary (0xa)
151 		 * OR'ed with enabled (0x50) = 0xf
152 		 */
153 		dm_pci_write_config8(dev, 0x09, 0x8f);
154 
155 		/* Set timings */
156 		dm_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
157 				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
158 				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
159 		dm_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
160 				IDE_SITRE | IDE_ISP_3_CLOCKS |
161 				IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
162 
163 		/* Sync DMA */
164 		dm_pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
165 		dm_pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
166 
167 		common_sata_init(dev, port_map);
168 	}
169 
170 	/* Set Gen3 Transmitter settings if needed */
171 	port_tx = fdtdec_get_int(blob, node, "intel,sata-port0-gen3-tx", 0);
172 	if (port_tx)
173 		pch_iobp_update(pch, SATA_IOBP_SP0G3IR, 0, port_tx);
174 
175 	port_tx = fdtdec_get_int(blob, node, "intel,sata-port1-gen3-tx", 0);
176 	if (port_tx)
177 		pch_iobp_update(pch, SATA_IOBP_SP1G3IR, 0, port_tx);
178 
179 	/* Additional Programming Requirements */
180 	sir_write(dev, 0x04, 0x00001600);
181 	sir_write(dev, 0x28, 0xa0000033);
182 	reg32 = sir_read(dev, 0x54);
183 	reg32 &= 0xff000000;
184 	reg32 |= 0x5555aa;
185 	sir_write(dev, 0x54, reg32);
186 	sir_write(dev, 0x64, 0xcccc8484);
187 	reg32 = sir_read(dev, 0x68);
188 	reg32 &= 0xffff0000;
189 	reg32 |= 0xcccc;
190 	sir_write(dev, 0x68, reg32);
191 	reg32 = sir_read(dev, 0x78);
192 	reg32 &= 0x0000ffff;
193 	reg32 |= 0x88880000;
194 	sir_write(dev, 0x78, reg32);
195 	sir_write(dev, 0x84, 0x001c7000);
196 	sir_write(dev, 0x88, 0x88338822);
197 	sir_write(dev, 0xa0, 0x001c7000);
198 	sir_write(dev, 0xc4, 0x0c0c0c0c);
199 	sir_write(dev, 0xc8, 0x0c0c0c0c);
200 	sir_write(dev, 0xd4, 0x10000000);
201 
202 	pch_iobp_update(pch, 0xea004001, 0x3fffffff, 0xc0000000);
203 	pch_iobp_update(pch, 0xea00408a, 0xfffffcff, 0x00000100);
204 }
205 
206 static void bd82x6x_sata_enable(struct udevice *dev)
207 {
208 	const void *blob = gd->fdt_blob;
209 	int node = dev->of_offset;
210 	unsigned port_map;
211 	const char *mode;
212 	u16 map = 0;
213 
214 	/*
215 	 * Set SATA controller mode early so the resource allocator can
216 	 * properly assign IO/Memory resources for the controller.
217 	 */
218 	mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
219 	if (mode && !strcmp(mode, "ahci"))
220 		map = 0x0060;
221 	port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
222 
223 	map |= (port_map ^ 0x3f) << 8;
224 	dm_pci_write_config16(dev, 0x90, map);
225 }
226 
227 static int bd82x6x_sata_probe(struct udevice *dev)
228 {
229 	struct udevice *pch;
230 	int ret;
231 
232 	ret = uclass_first_device(UCLASS_PCH, &pch);
233 	if (ret)
234 		return ret;
235 	if (!pch)
236 		return -ENODEV;
237 
238 	if (!(gd->flags & GD_FLG_RELOC))
239 		bd82x6x_sata_enable(dev);
240 	else
241 		bd82x6x_sata_init(dev, pch);
242 
243 	return 0;
244 }
245 
246 static const struct udevice_id bd82x6x_ahci_ids[] = {
247 	{ .compatible = "intel,pantherpoint-ahci" },
248 	{ }
249 };
250 
251 U_BOOT_DRIVER(ahci_ivybridge_drv) = {
252 	.name		= "ahci_ivybridge",
253 	.id		= UCLASS_DISK,
254 	.of_match	= bd82x6x_ahci_ids,
255 	.probe		= bd82x6x_sata_probe,
256 };
257