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