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