blob: 94d7369351a32ae398c2d62ac06bc03f9f28498d [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Tor Krill169789d2015-12-03 12:38:02 +01002/*
3 * Copyright (C) Excito Elektronik i Skåne AB, 2010.
4 * Author: Tor Krill <tor@excito.com>
5 *
Stefan Roese05066202019-03-11 13:29:20 +01006 * Copyright (C) 2015, 2019 Stefan Roese <sr@denx.de>
Tor Krill169789d2015-12-03 12:38:02 +01007 */
8
9/*
10 * This driver supports the SATA controller of some Mavell SoC's.
11 * Here a (most likely incomplete) list of the supported SoC's:
12 * - Kirkwood
13 * - Armada 370
14 * - Armada XP
15 *
16 * This driver implementation is an alternative to the already available
17 * driver via the "ide" commands interface (drivers/block/mvsata_ide.c).
18 * But this driver only supports PIO mode and as this new driver also
19 * supports transfer via DMA, its much faster.
20 *
21 * Please note, that the newer SoC's (e.g. Armada 38x) are not supported
22 * by this driver. As they have an AHCI compatible SATA controller
23 * integrated.
24 */
25
26/*
27 * TODO:
28 * Better error recovery
29 * No support for using PRDs (Thus max 64KB transfers)
30 * No NCQ support
31 * No port multiplier support
32 */
33
34#include <common.h>
Stefan Roese05066202019-03-11 13:29:20 +010035#include <ahci.h>
Simon Glasse6f6f9e2020-05-10 11:39:58 -060036#include <blk.h>
Tony Dinh19acf772023-09-05 22:22:41 -070037#include <bootdev.h>
Simon Glass1eb69ae2019-11-14 12:57:39 -070038#include <cpu_func.h>
Stefan Roese05066202019-03-11 13:29:20 +010039#include <dm.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060040#include <log.h>
Simon Glass90526e92020-05-10 11:39:56 -060041#include <asm/cache.h>
Simon Glass401d1c42020-10-30 21:38:53 -060042#include <asm/global_data.h>
Stefan Roese05066202019-03-11 13:29:20 +010043#include <dm/device-internal.h>
44#include <dm/lists.h>
Tor Krill169789d2015-12-03 12:38:02 +010045#include <fis.h>
46#include <libata.h>
47#include <malloc.h>
48#include <sata.h>
Simon Glasscd93d622020-05-10 11:40:13 -060049#include <linux/bitops.h>
Simon Glassc05ed002020-05-10 11:40:11 -060050#include <linux/delay.h>
Masahiro Yamada1221ce42016-09-21 11:28:55 +090051#include <linux/errno.h>
Tor Krill169789d2015-12-03 12:38:02 +010052#include <asm/io.h>
53#include <linux/mbus.h>
54
Michael Walle6d294972019-04-03 23:28:29 +020055#include <asm/arch/soc.h>
Trevor Woernerbb0fb4c2020-05-06 08:02:40 -040056#if defined(CONFIG_ARCH_KIRKWOOD)
Tor Krill169789d2015-12-03 12:38:02 +010057#define SATAHC_BASE KW_SATA_BASE
58#else
Tor Krill169789d2015-12-03 12:38:02 +010059#define SATAHC_BASE MVEBU_AXP_SATA_BASE
60#endif
61
62#define SATA0_BASE (SATAHC_BASE + 0x2000)
63#define SATA1_BASE (SATAHC_BASE + 0x4000)
64
65/* EDMA registers */
66#define EDMA_CFG 0x000
67#define EDMA_CFG_NCQ (1 << 5)
68#define EDMA_CFG_EQUE (1 << 9)
69#define EDMA_TIMER 0x004
70#define EDMA_IECR 0x008
71#define EDMA_IEMR 0x00c
72#define EDMA_RQBA_HI 0x010
73#define EDMA_RQIPR 0x014
74#define EDMA_RQIPR_IPMASK (0x1f << 5)
75#define EDMA_RQIPR_IPSHIFT 5
76#define EDMA_RQOPR 0x018
77#define EDMA_RQOPR_OPMASK (0x1f << 5)
78#define EDMA_RQOPR_OPSHIFT 5
79#define EDMA_RSBA_HI 0x01c
80#define EDMA_RSIPR 0x020
81#define EDMA_RSIPR_IPMASK (0x1f << 3)
82#define EDMA_RSIPR_IPSHIFT 3
83#define EDMA_RSOPR 0x024
84#define EDMA_RSOPR_OPMASK (0x1f << 3)
85#define EDMA_RSOPR_OPSHIFT 3
86#define EDMA_CMD 0x028
87#define EDMA_CMD_ENEDMA (0x01 << 0)
88#define EDMA_CMD_DISEDMA (0x01 << 1)
89#define EDMA_CMD_ATARST (0x01 << 2)
90#define EDMA_CMD_FREEZE (0x01 << 4)
91#define EDMA_TEST_CTL 0x02c
92#define EDMA_STATUS 0x030
93#define EDMA_IORTO 0x034
94#define EDMA_CDTR 0x040
95#define EDMA_HLTCND 0x060
96#define EDMA_NTSR 0x094
97
98/* Basic DMA registers */
99#define BDMA_CMD 0x224
100#define BDMA_STATUS 0x228
101#define BDMA_DTLB 0x22c
102#define BDMA_DTHB 0x230
103#define BDMA_DRL 0x234
104#define BDMA_DRH 0x238
105
106/* SATA Interface registers */
107#define SIR_ICFG 0x050
108#define SIR_CFG_GEN2EN (0x1 << 7)
109#define SIR_PLL_CFG 0x054
110#define SIR_SSTATUS 0x300
111#define SSTATUS_DET_MASK (0x0f << 0)
112#define SIR_SERROR 0x304
113#define SIR_SCONTROL 0x308
114#define SIR_SCONTROL_DETEN (0x01 << 0)
115#define SIR_LTMODE 0x30c
116#define SIR_LTMODE_NELBE (0x01 << 7)
117#define SIR_PHYMODE3 0x310
118#define SIR_PHYMODE4 0x314
119#define SIR_PHYMODE1 0x32c
120#define SIR_PHYMODE2 0x330
121#define SIR_BIST_CTRL 0x334
122#define SIR_BIST_DW1 0x338
123#define SIR_BIST_DW2 0x33c
124#define SIR_SERR_IRQ_MASK 0x340
125#define SIR_SATA_IFCTRL 0x344
126#define SIR_SATA_TESTCTRL 0x348
127#define SIR_SATA_IFSTATUS 0x34c
128#define SIR_VEND_UNIQ 0x35c
129#define SIR_FIS_CFG 0x360
130#define SIR_FIS_IRQ_CAUSE 0x364
131#define SIR_FIS_IRQ_MASK 0x368
132#define SIR_FIS_DWORD0 0x370
133#define SIR_FIS_DWORD1 0x374
134#define SIR_FIS_DWORD2 0x378
135#define SIR_FIS_DWORD3 0x37c
136#define SIR_FIS_DWORD4 0x380
137#define SIR_FIS_DWORD5 0x384
138#define SIR_FIS_DWORD6 0x388
139#define SIR_PHYM9_GEN2 0x398
140#define SIR_PHYM9_GEN1 0x39c
141#define SIR_PHY_CFG 0x3a0
142#define SIR_PHYCTL 0x3a4
143#define SIR_PHYM10 0x3a8
144#define SIR_PHYM12 0x3b0
145
146/* Shadow registers */
147#define PIO_DATA 0x100
148#define PIO_ERR_FEATURES 0x104
149#define PIO_SECTOR_COUNT 0x108
150#define PIO_LBA_LOW 0x10c
151#define PIO_LBA_MID 0x110
152#define PIO_LBA_HI 0x114
153#define PIO_DEVICE 0x118
154#define PIO_CMD_STATUS 0x11c
155#define PIO_STATUS_ERR (0x01 << 0)
156#define PIO_STATUS_DRQ (0x01 << 3)
157#define PIO_STATUS_DF (0x01 << 5)
158#define PIO_STATUS_DRDY (0x01 << 6)
159#define PIO_STATUS_BSY (0x01 << 7)
160#define PIO_CTRL_ALTSTAT 0x120
161
162/* SATAHC arbiter registers */
163#define SATAHC_CFG 0x000
164#define SATAHC_RQOP 0x004
165#define SATAHC_RQIP 0x008
166#define SATAHC_ICT 0x00c
167#define SATAHC_ITT 0x010
168#define SATAHC_ICR 0x014
169#define SATAHC_ICR_PORT0 (0x01 << 0)
170#define SATAHC_ICR_PORT1 (0x01 << 1)
171#define SATAHC_MIC 0x020
172#define SATAHC_MIM 0x024
173#define SATAHC_LED_CFG 0x02c
174
175#define REQUEST_QUEUE_SIZE 32
176#define RESPONSE_QUEUE_SIZE REQUEST_QUEUE_SIZE
177
178struct crqb {
179 u32 dtb_low; /* DW0 */
180 u32 dtb_high; /* DW1 */
181 u32 control_flags; /* DW2 */
182 u32 drb_count; /* DW3 */
183 u32 ata_cmd_feat; /* DW4 */
184 u32 ata_addr; /* DW5 */
185 u32 ata_addr_exp; /* DW6 */
186 u32 ata_sect_count; /* DW7 */
187};
188
189#define CRQB_ALIGN 0x400
190
191#define CRQB_CNTRLFLAGS_DIR (0x01 << 0)
192#define CRQB_CNTRLFLAGS_DQTAGMASK (0x1f << 1)
193#define CRQB_CNTRLFLAGS_DQTAGSHIFT 1
194#define CRQB_CNTRLFLAGS_PMPORTMASK (0x0f << 12)
195#define CRQB_CNTRLFLAGS_PMPORTSHIFT 12
196#define CRQB_CNTRLFLAGS_PRDMODE (0x01 << 16)
197#define CRQB_CNTRLFLAGS_HQTAGMASK (0x1f << 17)
198#define CRQB_CNTRLFLAGS_HQTAGSHIFT 17
199
200#define CRQB_CMDFEAT_CMDMASK (0xff << 16)
201#define CRQB_CMDFEAT_CMDSHIFT 16
202#define CRQB_CMDFEAT_FEATMASK (0xff << 16)
203#define CRQB_CMDFEAT_FEATSHIFT 24
204
205#define CRQB_ADDR_LBA_LOWMASK (0xff << 0)
206#define CRQB_ADDR_LBA_LOWSHIFT 0
207#define CRQB_ADDR_LBA_MIDMASK (0xff << 8)
208#define CRQB_ADDR_LBA_MIDSHIFT 8
209#define CRQB_ADDR_LBA_HIGHMASK (0xff << 16)
210#define CRQB_ADDR_LBA_HIGHSHIFT 16
211#define CRQB_ADDR_DEVICE_MASK (0xff << 24)
212#define CRQB_ADDR_DEVICE_SHIFT 24
213
214#define CRQB_ADDR_LBA_LOW_EXP_MASK (0xff << 0)
215#define CRQB_ADDR_LBA_LOW_EXP_SHIFT 0
216#define CRQB_ADDR_LBA_MID_EXP_MASK (0xff << 8)
217#define CRQB_ADDR_LBA_MID_EXP_SHIFT 8
218#define CRQB_ADDR_LBA_HIGH_EXP_MASK (0xff << 16)
219#define CRQB_ADDR_LBA_HIGH_EXP_SHIFT 16
220#define CRQB_ADDR_FEATURE_EXP_MASK (0xff << 24)
221#define CRQB_ADDR_FEATURE_EXP_SHIFT 24
222
223#define CRQB_SECTCOUNT_COUNT_MASK (0xff << 0)
224#define CRQB_SECTCOUNT_COUNT_SHIFT 0
225#define CRQB_SECTCOUNT_COUNT_EXP_MASK (0xff << 8)
226#define CRQB_SECTCOUNT_COUNT_EXP_SHIFT 8
227
Michael Walle6d294972019-04-03 23:28:29 +0200228#define MVSATA_WIN_CONTROL(w) (SATAHC_BASE + 0x30 + ((w) << 4))
229#define MVSATA_WIN_BASE(w) (SATAHC_BASE + 0x34 + ((w) << 4))
Tor Krill169789d2015-12-03 12:38:02 +0100230
231struct eprd {
232 u32 phyaddr_low;
233 u32 bytecount_eot;
234 u32 phyaddr_hi;
235 u32 reserved;
236};
237
238#define EPRD_PHYADDR_MASK 0xfffffffe
239#define EPRD_BYTECOUNT_MASK 0x0000ffff
240#define EPRD_EOT (0x01 << 31)
241
242struct crpb {
243 u32 id;
244 u32 flags;
245 u32 timestamp;
246};
247
248#define CRPB_ALIGN 0x100
249
250#define READ_CMD 0
251#define WRITE_CMD 1
252
253/*
254 * Since we don't use PRDs yet max transfer size
255 * is 64KB
256 */
257#define MV_ATA_MAX_SECTORS (65535 / ATA_SECT_SIZE)
258
259/* Keep track if hw is initialized or not */
260static u32 hw_init;
261
262struct mv_priv {
263 char name[12];
264 u32 link;
265 u32 regbase;
266 u32 queue_depth;
267 u16 pio;
268 u16 mwdma;
269 u16 udma;
Stefan Roese05066202019-03-11 13:29:20 +0100270 int dev_nr;
Tor Krill169789d2015-12-03 12:38:02 +0100271
272 void *crqb_alloc;
273 struct crqb *request;
274
275 void *crpb_alloc;
276 struct crpb *response;
277};
278
279static int ata_wait_register(u32 *addr, u32 mask, u32 val, u32 timeout_msec)
280{
281 ulong start;
282
283 start = get_timer(0);
284 do {
285 if ((in_le32(addr) & mask) == val)
286 return 0;
287 } while (get_timer(start) < timeout_msec);
288
289 return -ETIMEDOUT;
290}
291
292/* Cut from sata_mv in linux kernel */
Stefan Roese05066202019-03-11 13:29:20 +0100293static int mv_stop_edma_engine(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100294{
Simon Glassc69cda22020-12-03 16:55:20 -0700295 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100296 int i;
297
298 /* Disable eDMA. The disable bit auto clears. */
299 out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_DISEDMA);
300
301 /* Wait for the chip to confirm eDMA is off. */
302 for (i = 10000; i > 0; i--) {
303 u32 reg = in_le32(priv->regbase + EDMA_CMD);
304 if (!(reg & EDMA_CMD_ENEDMA)) {
305 debug("EDMA stop on port %d succesful\n", port);
306 return 0;
307 }
308 udelay(10);
309 }
310 debug("EDMA stop on port %d failed\n", port);
311 return -1;
312}
313
Stefan Roese05066202019-03-11 13:29:20 +0100314static int mv_start_edma_engine(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100315{
Simon Glassc69cda22020-12-03 16:55:20 -0700316 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100317 u32 tmp;
318
319 /* Check preconditions */
320 tmp = in_le32(priv->regbase + SIR_SSTATUS);
321 if ((tmp & SSTATUS_DET_MASK) != 0x03) {
322 printf("Device error on port: %d\n", port);
323 return -1;
324 }
325
326 tmp = in_le32(priv->regbase + PIO_CMD_STATUS);
327 if (tmp & (ATA_BUSY | ATA_DRQ)) {
328 printf("Device not ready on port: %d\n", port);
329 return -1;
330 }
331
332 /* Clear interrupt cause */
333 out_le32(priv->regbase + EDMA_IECR, 0x0);
334
335 tmp = in_le32(SATAHC_BASE + SATAHC_ICR);
336 tmp &= ~(port == 0 ? SATAHC_ICR_PORT0 : SATAHC_ICR_PORT1);
337 out_le32(SATAHC_BASE + SATAHC_ICR, tmp);
338
339 /* Configure edma operation */
340 tmp = in_le32(priv->regbase + EDMA_CFG);
341 tmp &= ~EDMA_CFG_NCQ; /* No NCQ */
342 tmp &= ~EDMA_CFG_EQUE; /* Dont queue operations */
343 out_le32(priv->regbase + EDMA_CFG, tmp);
344
345 out_le32(priv->regbase + SIR_FIS_IRQ_CAUSE, 0x0);
346
347 /* Configure fis, set all to no-wait for now */
348 out_le32(priv->regbase + SIR_FIS_CFG, 0x0);
349
350 /* Setup request queue */
351 out_le32(priv->regbase + EDMA_RQBA_HI, 0x0);
352 out_le32(priv->regbase + EDMA_RQIPR, priv->request);
353 out_le32(priv->regbase + EDMA_RQOPR, 0x0);
354
355 /* Setup response queue */
356 out_le32(priv->regbase + EDMA_RSBA_HI, 0x0);
357 out_le32(priv->regbase + EDMA_RSOPR, priv->response);
358 out_le32(priv->regbase + EDMA_RSIPR, 0x0);
359
360 /* Start edma */
361 out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_ENEDMA);
362
363 return 0;
364}
365
Stefan Roese05066202019-03-11 13:29:20 +0100366static int mv_reset_channel(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100367{
Simon Glassc69cda22020-12-03 16:55:20 -0700368 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100369
370 /* Make sure edma is stopped */
Stefan Roese05066202019-03-11 13:29:20 +0100371 mv_stop_edma_engine(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +0100372
373 out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_ATARST);
374 udelay(25); /* allow reset propagation */
375 out_le32(priv->regbase + EDMA_CMD, 0);
376 mdelay(10);
377
378 return 0;
379}
380
Stefan Roese05066202019-03-11 13:29:20 +0100381static void mv_reset_port(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100382{
Simon Glassc69cda22020-12-03 16:55:20 -0700383 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100384
Stefan Roese05066202019-03-11 13:29:20 +0100385 mv_reset_channel(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +0100386
387 out_le32(priv->regbase + EDMA_CMD, 0x0);
388 out_le32(priv->regbase + EDMA_CFG, 0x101f);
389 out_le32(priv->regbase + EDMA_IECR, 0x0);
390 out_le32(priv->regbase + EDMA_IEMR, 0x0);
391 out_le32(priv->regbase + EDMA_RQBA_HI, 0x0);
392 out_le32(priv->regbase + EDMA_RQIPR, 0x0);
393 out_le32(priv->regbase + EDMA_RQOPR, 0x0);
394 out_le32(priv->regbase + EDMA_RSBA_HI, 0x0);
395 out_le32(priv->regbase + EDMA_RSIPR, 0x0);
396 out_le32(priv->regbase + EDMA_RSOPR, 0x0);
397 out_le32(priv->regbase + EDMA_IORTO, 0xfa);
398}
399
400static void mv_reset_one_hc(void)
401{
402 out_le32(SATAHC_BASE + SATAHC_ICT, 0x00);
403 out_le32(SATAHC_BASE + SATAHC_ITT, 0x00);
404 out_le32(SATAHC_BASE + SATAHC_ICR, 0x00);
405}
406
Stefan Roese05066202019-03-11 13:29:20 +0100407static int probe_port(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100408{
Simon Glassc69cda22020-12-03 16:55:20 -0700409 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100410 int tries, tries2, set15 = 0;
411 u32 tmp;
412
413 debug("Probe port: %d\n", port);
414
415 for (tries = 0; tries < 2; tries++) {
416 /* Clear SError */
417 out_le32(priv->regbase + SIR_SERROR, 0x0);
418
419 /* trigger com-init */
420 tmp = in_le32(priv->regbase + SIR_SCONTROL);
421 tmp = (tmp & 0x0f0) | 0x300 | SIR_SCONTROL_DETEN;
422 out_le32(priv->regbase + SIR_SCONTROL, tmp);
423
424 mdelay(1);
425
426 tmp = in_le32(priv->regbase + SIR_SCONTROL);
427 tries2 = 5;
428 do {
429 tmp = (tmp & 0x0f0) | 0x300;
430 out_le32(priv->regbase + SIR_SCONTROL, tmp);
431 mdelay(10);
432 tmp = in_le32(priv->regbase + SIR_SCONTROL);
433 } while ((tmp & 0xf0f) != 0x300 && tries2--);
434
435 mdelay(10);
436
437 for (tries2 = 0; tries2 < 200; tries2++) {
438 tmp = in_le32(priv->regbase + SIR_SSTATUS);
439 if ((tmp & SSTATUS_DET_MASK) == 0x03) {
440 debug("Found device on port\n");
441 return 0;
442 }
443 mdelay(1);
444 }
445
446 if ((tmp & SSTATUS_DET_MASK) == 0) {
447 debug("No device attached on port %d\n", port);
448 return -ENODEV;
449 }
450
451 if (!set15) {
452 /* Try on 1.5Gb/S */
453 debug("Try 1.5Gb link\n");
454 set15 = 1;
455 out_le32(priv->regbase + SIR_SCONTROL, 0x304);
456
457 tmp = in_le32(priv->regbase + SIR_ICFG);
458 tmp &= ~SIR_CFG_GEN2EN;
459 out_le32(priv->regbase + SIR_ICFG, tmp);
460
Stefan Roese05066202019-03-11 13:29:20 +0100461 mv_reset_channel(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +0100462 }
463 }
464
465 debug("Failed to probe port\n");
466 return -1;
467}
468
469/* Get request queue in pointer */
Stefan Roese05066202019-03-11 13:29:20 +0100470static int get_reqip(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100471{
Simon Glassc69cda22020-12-03 16:55:20 -0700472 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100473 u32 tmp;
474
475 tmp = in_le32(priv->regbase + EDMA_RQIPR) & EDMA_RQIPR_IPMASK;
476 tmp = tmp >> EDMA_RQIPR_IPSHIFT;
477
478 return tmp;
479}
480
Stefan Roese05066202019-03-11 13:29:20 +0100481static void set_reqip(struct udevice *dev, int port, int reqin)
Tor Krill169789d2015-12-03 12:38:02 +0100482{
Simon Glassc69cda22020-12-03 16:55:20 -0700483 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100484 u32 tmp;
485
486 tmp = in_le32(priv->regbase + EDMA_RQIPR) & ~EDMA_RQIPR_IPMASK;
487 tmp |= ((reqin << EDMA_RQIPR_IPSHIFT) & EDMA_RQIPR_IPMASK);
488 out_le32(priv->regbase + EDMA_RQIPR, tmp);
489}
490
491/* Get next available slot, ignoring possible overwrite */
Stefan Roese05066202019-03-11 13:29:20 +0100492static int get_next_reqip(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100493{
Stefan Roese05066202019-03-11 13:29:20 +0100494 int slot = get_reqip(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +0100495 slot = (slot + 1) % REQUEST_QUEUE_SIZE;
496 return slot;
497}
498
499/* Get response queue in pointer */
Stefan Roese05066202019-03-11 13:29:20 +0100500static int get_rspip(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100501{
Simon Glassc69cda22020-12-03 16:55:20 -0700502 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100503 u32 tmp;
504
505 tmp = in_le32(priv->regbase + EDMA_RSIPR) & EDMA_RSIPR_IPMASK;
506 tmp = tmp >> EDMA_RSIPR_IPSHIFT;
507
508 return tmp;
509}
510
511/* Get response queue out pointer */
Stefan Roese05066202019-03-11 13:29:20 +0100512static int get_rspop(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100513{
Simon Glassc69cda22020-12-03 16:55:20 -0700514 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100515 u32 tmp;
516
517 tmp = in_le32(priv->regbase + EDMA_RSOPR) & EDMA_RSOPR_OPMASK;
518 tmp = tmp >> EDMA_RSOPR_OPSHIFT;
519 return tmp;
520}
521
522/* Get next response queue pointer */
Stefan Roese05066202019-03-11 13:29:20 +0100523static int get_next_rspop(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100524{
Stefan Roese05066202019-03-11 13:29:20 +0100525 return (get_rspop(dev, port) + 1) % RESPONSE_QUEUE_SIZE;
Tor Krill169789d2015-12-03 12:38:02 +0100526}
527
528/* Set response queue pointer */
Stefan Roese05066202019-03-11 13:29:20 +0100529static void set_rspop(struct udevice *dev, int port, int reqin)
Tor Krill169789d2015-12-03 12:38:02 +0100530{
Simon Glassc69cda22020-12-03 16:55:20 -0700531 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100532 u32 tmp;
533
534 tmp = in_le32(priv->regbase + EDMA_RSOPR) & ~EDMA_RSOPR_OPMASK;
535 tmp |= ((reqin << EDMA_RSOPR_OPSHIFT) & EDMA_RSOPR_OPMASK);
536
537 out_le32(priv->regbase + EDMA_RSOPR, tmp);
538}
539
Stefan Roese05066202019-03-11 13:29:20 +0100540static int wait_dma_completion(struct udevice *dev, int port, int index,
541 u32 timeout_msec)
Tor Krill169789d2015-12-03 12:38:02 +0100542{
543 u32 tmp, res;
544
545 tmp = port == 0 ? SATAHC_ICR_PORT0 : SATAHC_ICR_PORT1;
546 res = ata_wait_register((u32 *)(SATAHC_BASE + SATAHC_ICR), tmp,
547 tmp, timeout_msec);
548 if (res)
549 printf("Failed to wait for completion on port %d\n", port);
550
551 return res;
552}
553
Stefan Roese05066202019-03-11 13:29:20 +0100554static void process_responses(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100555{
556#ifdef DEBUG
Simon Glassc69cda22020-12-03 16:55:20 -0700557 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100558#endif
559 u32 tmp;
Stefan Roese05066202019-03-11 13:29:20 +0100560 u32 outind = get_rspop(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +0100561
562 /* Ack interrupts */
563 tmp = in_le32(SATAHC_BASE + SATAHC_ICR);
564 if (port == 0)
565 tmp &= ~(BIT(0) | BIT(8));
566 else
567 tmp &= ~(BIT(1) | BIT(9));
568 tmp &= ~(BIT(4));
569 out_le32(SATAHC_BASE + SATAHC_ICR, tmp);
570
Stefan Roese05066202019-03-11 13:29:20 +0100571 while (get_rspip(dev, port) != outind) {
Tor Krill169789d2015-12-03 12:38:02 +0100572#ifdef DEBUG
573 debug("Response index %d flags %08x on port %d\n", outind,
574 priv->response[outind].flags, port);
575#endif
Stefan Roese05066202019-03-11 13:29:20 +0100576 outind = get_next_rspop(dev, port);
577 set_rspop(dev, port, outind);
Tor Krill169789d2015-12-03 12:38:02 +0100578 }
579}
580
Stefan Roese05066202019-03-11 13:29:20 +0100581static int mv_ata_exec_ata_cmd(struct udevice *dev, int port,
582 struct sata_fis_h2d *cfis,
Tor Krill169789d2015-12-03 12:38:02 +0100583 u8 *buffer, u32 len, u32 iswrite)
584{
Simon Glassc69cda22020-12-03 16:55:20 -0700585 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100586 struct crqb *req;
587 int slot;
Stefan Roese5102af42016-11-18 17:21:51 +0100588 u32 start;
Tor Krill169789d2015-12-03 12:38:02 +0100589
590 if (len >= 64 * 1024) {
591 printf("We only support <64K transfers for now\n");
592 return -1;
593 }
594
595 /* Initialize request */
Stefan Roese05066202019-03-11 13:29:20 +0100596 slot = get_reqip(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +0100597 memset(&priv->request[slot], 0, sizeof(struct crqb));
598 req = &priv->request[slot];
599
600 req->dtb_low = (u32)buffer;
601
602 /* Dont use PRDs */
603 req->control_flags = CRQB_CNTRLFLAGS_PRDMODE;
604 req->control_flags |= iswrite ? 0 : CRQB_CNTRLFLAGS_DIR;
605 req->control_flags |=
606 ((cfis->pm_port_c << CRQB_CNTRLFLAGS_PMPORTSHIFT)
607 & CRQB_CNTRLFLAGS_PMPORTMASK);
608
609 req->drb_count = len;
610
611 req->ata_cmd_feat = (cfis->command << CRQB_CMDFEAT_CMDSHIFT) &
612 CRQB_CMDFEAT_CMDMASK;
613 req->ata_cmd_feat |= (cfis->features << CRQB_CMDFEAT_FEATSHIFT) &
614 CRQB_CMDFEAT_FEATMASK;
615
616 req->ata_addr = (cfis->lba_low << CRQB_ADDR_LBA_LOWSHIFT) &
617 CRQB_ADDR_LBA_LOWMASK;
618 req->ata_addr |= (cfis->lba_mid << CRQB_ADDR_LBA_MIDSHIFT) &
619 CRQB_ADDR_LBA_MIDMASK;
620 req->ata_addr |= (cfis->lba_high << CRQB_ADDR_LBA_HIGHSHIFT) &
621 CRQB_ADDR_LBA_HIGHMASK;
622 req->ata_addr |= (cfis->device << CRQB_ADDR_DEVICE_SHIFT) &
623 CRQB_ADDR_DEVICE_MASK;
624
625 req->ata_addr_exp = (cfis->lba_low_exp << CRQB_ADDR_LBA_LOW_EXP_SHIFT) &
626 CRQB_ADDR_LBA_LOW_EXP_MASK;
627 req->ata_addr_exp |=
628 (cfis->lba_mid_exp << CRQB_ADDR_LBA_MID_EXP_SHIFT) &
629 CRQB_ADDR_LBA_MID_EXP_MASK;
630 req->ata_addr_exp |=
631 (cfis->lba_high_exp << CRQB_ADDR_LBA_HIGH_EXP_SHIFT) &
632 CRQB_ADDR_LBA_HIGH_EXP_MASK;
633 req->ata_addr_exp |=
634 (cfis->features_exp << CRQB_ADDR_FEATURE_EXP_SHIFT) &
635 CRQB_ADDR_FEATURE_EXP_MASK;
636
637 req->ata_sect_count =
638 (cfis->sector_count << CRQB_SECTCOUNT_COUNT_SHIFT) &
639 CRQB_SECTCOUNT_COUNT_MASK;
640 req->ata_sect_count |=
641 (cfis->sector_count_exp << CRQB_SECTCOUNT_COUNT_EXP_SHIFT) &
642 CRQB_SECTCOUNT_COUNT_EXP_MASK;
643
644 /* Flush data */
Stefan Roese5102af42016-11-18 17:21:51 +0100645 start = (u32)req & ~(ARCH_DMA_MINALIGN - 1);
646 flush_dcache_range(start,
647 start + ALIGN(sizeof(*req), ARCH_DMA_MINALIGN));
Tor Krill169789d2015-12-03 12:38:02 +0100648
649 /* Trigger operation */
Stefan Roese05066202019-03-11 13:29:20 +0100650 slot = get_next_reqip(dev, port);
651 set_reqip(dev, port, slot);
Tor Krill169789d2015-12-03 12:38:02 +0100652
653 /* Wait for completion */
Stefan Roese05066202019-03-11 13:29:20 +0100654 if (wait_dma_completion(dev, port, slot, 10000)) {
Tor Krill169789d2015-12-03 12:38:02 +0100655 printf("ATA operation timed out\n");
656 return -1;
657 }
658
Stefan Roese05066202019-03-11 13:29:20 +0100659 process_responses(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +0100660
661 /* Invalidate data on read */
Stefan Roese5102af42016-11-18 17:21:51 +0100662 if (buffer && len) {
663 start = (u32)buffer & ~(ARCH_DMA_MINALIGN - 1);
664 invalidate_dcache_range(start,
665 start + ALIGN(len, ARCH_DMA_MINALIGN));
666 }
Tor Krill169789d2015-12-03 12:38:02 +0100667
668 return len;
669}
670
Stefan Roese05066202019-03-11 13:29:20 +0100671static u32 mv_sata_rw_cmd_ext(struct udevice *dev, int port, lbaint_t start,
672 u32 blkcnt,
Tor Krill169789d2015-12-03 12:38:02 +0100673 u8 *buffer, int is_write)
674{
675 struct sata_fis_h2d cfis;
676 u32 res;
677 u64 block;
678
679 block = (u64)start;
680
681 memset(&cfis, 0, sizeof(struct sata_fis_h2d));
682
683 cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
684 cfis.command = (is_write) ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
685
686 cfis.lba_high_exp = (block >> 40) & 0xff;
687 cfis.lba_mid_exp = (block >> 32) & 0xff;
688 cfis.lba_low_exp = (block >> 24) & 0xff;
689 cfis.lba_high = (block >> 16) & 0xff;
690 cfis.lba_mid = (block >> 8) & 0xff;
691 cfis.lba_low = block & 0xff;
692 cfis.device = ATA_LBA;
693 cfis.sector_count_exp = (blkcnt >> 8) & 0xff;
694 cfis.sector_count = blkcnt & 0xff;
695
Stefan Roese05066202019-03-11 13:29:20 +0100696 res = mv_ata_exec_ata_cmd(dev, port, &cfis, buffer,
697 ATA_SECT_SIZE * blkcnt, is_write);
Tor Krill169789d2015-12-03 12:38:02 +0100698
699 return res >= 0 ? blkcnt : res;
700}
701
Stefan Roese05066202019-03-11 13:29:20 +0100702static u32 mv_sata_rw_cmd(struct udevice *dev, int port, lbaint_t start,
703 u32 blkcnt, u8 *buffer, int is_write)
Tor Krill169789d2015-12-03 12:38:02 +0100704{
705 struct sata_fis_h2d cfis;
706 lbaint_t block;
707 u32 res;
708
709 block = start;
710
711 memset(&cfis, 0, sizeof(struct sata_fis_h2d));
712
713 cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
714 cfis.command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
715 cfis.device = ATA_LBA;
716
717 cfis.device |= (block >> 24) & 0xf;
718 cfis.lba_high = (block >> 16) & 0xff;
719 cfis.lba_mid = (block >> 8) & 0xff;
720 cfis.lba_low = block & 0xff;
721 cfis.sector_count = (u8)(blkcnt & 0xff);
722
Stefan Roese05066202019-03-11 13:29:20 +0100723 res = mv_ata_exec_ata_cmd(dev, port, &cfis, buffer,
724 ATA_SECT_SIZE * blkcnt, is_write);
Tor Krill169789d2015-12-03 12:38:02 +0100725
726 return res >= 0 ? blkcnt : res;
727}
728
Stefan Roese05066202019-03-11 13:29:20 +0100729static u32 ata_low_level_rw(struct udevice *dev, int port, lbaint_t blknr,
730 lbaint_t blkcnt, void *buffer, int is_write)
Tor Krill169789d2015-12-03 12:38:02 +0100731{
Simon Glasscaa4daa2020-12-03 16:55:18 -0700732 struct blk_desc *desc = dev_get_uclass_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100733 lbaint_t start, blks;
734 u8 *addr;
735 int max_blks;
736
Michael Wallecfdf6322019-04-03 23:28:28 +0200737 debug("%s: " LBAFU " " LBAFU "\n", __func__, blknr, blkcnt);
Tor Krill169789d2015-12-03 12:38:02 +0100738
739 start = blknr;
740 blks = blkcnt;
741 addr = (u8 *)buffer;
742
743 max_blks = MV_ATA_MAX_SECTORS;
744 do {
745 if (blks > max_blks) {
Stefan Roese05066202019-03-11 13:29:20 +0100746 if (desc->lba48) {
747 mv_sata_rw_cmd_ext(dev, port, start, max_blks,
748 addr, is_write);
Tor Krill169789d2015-12-03 12:38:02 +0100749 } else {
Stefan Roese05066202019-03-11 13:29:20 +0100750 mv_sata_rw_cmd(dev, port, start, max_blks,
751 addr, is_write);
Tor Krill169789d2015-12-03 12:38:02 +0100752 }
753 start += max_blks;
754 blks -= max_blks;
755 addr += ATA_SECT_SIZE * max_blks;
756 } else {
Stefan Roese05066202019-03-11 13:29:20 +0100757 if (desc->lba48) {
758 mv_sata_rw_cmd_ext(dev, port, start, blks, addr,
Tor Krill169789d2015-12-03 12:38:02 +0100759 is_write);
760 } else {
Stefan Roese05066202019-03-11 13:29:20 +0100761 mv_sata_rw_cmd(dev, port, start, blks, addr,
Tor Krill169789d2015-12-03 12:38:02 +0100762 is_write);
763 }
764 start += blks;
765 blks = 0;
766 addr += ATA_SECT_SIZE * blks;
767 }
768 } while (blks != 0);
769
770 return blkcnt;
771}
772
Stefan Roese05066202019-03-11 13:29:20 +0100773static int mv_ata_exec_ata_cmd_nondma(struct udevice *dev, int port,
Tor Krill169789d2015-12-03 12:38:02 +0100774 struct sata_fis_h2d *cfis, u8 *buffer,
775 u32 len, u32 iswrite)
776{
Simon Glassc69cda22020-12-03 16:55:20 -0700777 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100778 int i;
779 u16 *tp;
780
781 debug("%s\n", __func__);
782
783 out_le32(priv->regbase + PIO_SECTOR_COUNT, cfis->sector_count);
784 out_le32(priv->regbase + PIO_LBA_HI, cfis->lba_high);
785 out_le32(priv->regbase + PIO_LBA_MID, cfis->lba_mid);
786 out_le32(priv->regbase + PIO_LBA_LOW, cfis->lba_low);
787 out_le32(priv->regbase + PIO_ERR_FEATURES, cfis->features);
788 out_le32(priv->regbase + PIO_DEVICE, cfis->device);
789 out_le32(priv->regbase + PIO_CMD_STATUS, cfis->command);
790
791 if (ata_wait_register((u32 *)(priv->regbase + PIO_CMD_STATUS),
792 ATA_BUSY, 0x0, 10000)) {
793 debug("Failed to wait for completion\n");
794 return -1;
795 }
796
797 if (len > 0) {
798 tp = (u16 *)buffer;
799 for (i = 0; i < len / 2; i++) {
800 if (iswrite)
801 out_le16(priv->regbase + PIO_DATA, *tp++);
802 else
803 *tp++ = in_le16(priv->regbase + PIO_DATA);
804 }
805 }
806
807 return len;
808}
809
Stefan Roese05066202019-03-11 13:29:20 +0100810static int mv_sata_identify(struct udevice *dev, int port, u16 *id)
Tor Krill169789d2015-12-03 12:38:02 +0100811{
812 struct sata_fis_h2d h2d;
Tony Dinh7940d962021-07-31 20:29:35 -0700813 int len;
Tor Krill169789d2015-12-03 12:38:02 +0100814
815 memset(&h2d, 0, sizeof(struct sata_fis_h2d));
816
817 h2d.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
818 h2d.command = ATA_CMD_ID_ATA;
819
820 /* Give device time to get operational */
821 mdelay(10);
822
Tony Dinh7940d962021-07-31 20:29:35 -0700823 /* During cold start, with some HDDs, the first ATA ID command does
824 * not populate the ID words. In fact, the first ATA ID
825 * command will only power up the drive, and then the ATA ID command
826 * processing is lost in the process.
827 */
828 len = mv_ata_exec_ata_cmd_nondma(dev, port, &h2d, (u8 *)id,
829 ATA_ID_WORDS * 2, READ_CMD);
830
831 /* If drive capacity has been filled in, then it was successfully
832 * identified (the drive has been powered up before, i.e.
833 * this function is invoked during a reboot)
834 */
835 if (ata_id_n_sectors(id) != 0)
836 return len;
837
838 /* Issue the 2nd ATA ID command to make sure the ID words are
839 * populated properly.
840 */
841 mdelay(10);
842 len = mv_ata_exec_ata_cmd_nondma(dev, port, &h2d, (u8 *)id,
843 ATA_ID_WORDS * 2, READ_CMD);
844 if (ata_id_n_sectors(id) != 0)
845 return len;
846
847 printf("Err: Failed to identify SATA device %d\n", port);
848 return -ENODEV;
Tor Krill169789d2015-12-03 12:38:02 +0100849}
850
Stefan Roese05066202019-03-11 13:29:20 +0100851static void mv_sata_xfer_mode(struct udevice *dev, int port, u16 *id)
Tor Krill169789d2015-12-03 12:38:02 +0100852{
Simon Glassc69cda22020-12-03 16:55:20 -0700853 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100854
855 priv->pio = id[ATA_ID_PIO_MODES];
856 priv->mwdma = id[ATA_ID_MWDMA_MODES];
857 priv->udma = id[ATA_ID_UDMA_MODES];
858 debug("pio %04x, mwdma %04x, udma %04x\n", priv->pio, priv->mwdma,
859 priv->udma);
860}
861
Stefan Roese05066202019-03-11 13:29:20 +0100862static void mv_sata_set_features(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100863{
Simon Glassc69cda22020-12-03 16:55:20 -0700864 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100865 struct sata_fis_h2d cfis;
866 u8 udma_cap;
867
868 memset(&cfis, 0, sizeof(struct sata_fis_h2d));
869
870 cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
871 cfis.command = ATA_CMD_SET_FEATURES;
872 cfis.features = SETFEATURES_XFER;
873
874 /* First check the device capablity */
875 udma_cap = (u8) (priv->udma & 0xff);
876
877 if (udma_cap == ATA_UDMA6)
878 cfis.sector_count = XFER_UDMA_6;
879 if (udma_cap == ATA_UDMA5)
880 cfis.sector_count = XFER_UDMA_5;
881 if (udma_cap == ATA_UDMA4)
882 cfis.sector_count = XFER_UDMA_4;
883 if (udma_cap == ATA_UDMA3)
884 cfis.sector_count = XFER_UDMA_3;
885
Stefan Roese05066202019-03-11 13:29:20 +0100886 mv_ata_exec_ata_cmd_nondma(dev, port, &cfis, NULL, 0, READ_CMD);
Tor Krill169789d2015-12-03 12:38:02 +0100887}
888
889/*
890 * Initialize SATA memory windows
891 */
892static void mvsata_ide_conf_mbus_windows(void)
893{
894 const struct mbus_dram_target_info *dram;
895 int i;
896
897 dram = mvebu_mbus_dram_info();
898
899 /* Disable windows, Set Size/Base to 0 */
900 for (i = 0; i < 4; i++) {
901 writel(0, MVSATA_WIN_CONTROL(i));
902 writel(0, MVSATA_WIN_BASE(i));
903 }
904
905 for (i = 0; i < dram->num_cs; i++) {
906 const struct mbus_dram_window *cs = dram->cs + i;
907 writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
908 (dram->mbus_dram_target_id << 4) | 1,
909 MVSATA_WIN_CONTROL(i));
910 writel(cs->base & 0xffff0000, MVSATA_WIN_BASE(i));
911 }
912}
913
Stefan Roese05066202019-03-11 13:29:20 +0100914static int sata_mv_init_sata(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100915{
Simon Glassc69cda22020-12-03 16:55:20 -0700916 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100917
Stefan Roese05066202019-03-11 13:29:20 +0100918 debug("Initialize sata dev: %d\n", port);
Tor Krill169789d2015-12-03 12:38:02 +0100919
Stefan Roese05066202019-03-11 13:29:20 +0100920 if (port < 0 || port >= CONFIG_SYS_SATA_MAX_DEVICE) {
921 printf("Invalid sata device %d\n", port);
Tor Krill169789d2015-12-03 12:38:02 +0100922 return -1;
923 }
924
Tor Krill169789d2015-12-03 12:38:02 +0100925 /* Allocate and align request buffer */
926 priv->crqb_alloc = malloc(sizeof(struct crqb) * REQUEST_QUEUE_SIZE +
927 CRQB_ALIGN);
928 if (!priv->crqb_alloc) {
929 printf("Unable to allocate memory for request queue\n");
930 return -ENOMEM;
931 }
932 memset(priv->crqb_alloc, 0,
933 sizeof(struct crqb) * REQUEST_QUEUE_SIZE + CRQB_ALIGN);
934 priv->request = (struct crqb *)(((u32) priv->crqb_alloc + CRQB_ALIGN) &
935 ~(CRQB_ALIGN - 1));
936
937 /* Allocate and align response buffer */
938 priv->crpb_alloc = malloc(sizeof(struct crpb) * REQUEST_QUEUE_SIZE +
939 CRPB_ALIGN);
940 if (!priv->crpb_alloc) {
941 printf("Unable to allocate memory for response queue\n");
942 return -ENOMEM;
943 }
944 memset(priv->crpb_alloc, 0,
945 sizeof(struct crpb) * REQUEST_QUEUE_SIZE + CRPB_ALIGN);
946 priv->response = (struct crpb *)(((u32) priv->crpb_alloc + CRPB_ALIGN) &
947 ~(CRPB_ALIGN - 1));
948
Stefan Roese05066202019-03-11 13:29:20 +0100949 sprintf(priv->name, "SATA%d", port);
Tor Krill169789d2015-12-03 12:38:02 +0100950
Stefan Roese05066202019-03-11 13:29:20 +0100951 priv->regbase = port == 0 ? SATA0_BASE : SATA1_BASE;
Tor Krill169789d2015-12-03 12:38:02 +0100952
953 if (!hw_init) {
954 debug("Initialize sata hw\n");
955 hw_init = 1;
956 mv_reset_one_hc();
957 mvsata_ide_conf_mbus_windows();
958 }
959
Stefan Roese05066202019-03-11 13:29:20 +0100960 mv_reset_port(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +0100961
Stefan Roese05066202019-03-11 13:29:20 +0100962 if (probe_port(dev, port)) {
Tor Krill169789d2015-12-03 12:38:02 +0100963 priv->link = 0;
964 return -ENODEV;
965 }
966 priv->link = 1;
967
968 return 0;
969}
970
Stefan Roese05066202019-03-11 13:29:20 +0100971static int sata_mv_scan_sata(struct udevice *dev, int port)
Tor Krill169789d2015-12-03 12:38:02 +0100972{
Simon Glasscaa4daa2020-12-03 16:55:18 -0700973 struct blk_desc *desc = dev_get_uclass_plat(dev);
Simon Glassc69cda22020-12-03 16:55:20 -0700974 struct mv_priv *priv = dev_get_plat(dev);
Tor Krill169789d2015-12-03 12:38:02 +0100975 unsigned char serial[ATA_ID_SERNO_LEN + 1];
976 unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
977 unsigned char product[ATA_ID_PROD_LEN + 1];
978 u64 n_sectors;
979 u16 *id;
Tor Krill169789d2015-12-03 12:38:02 +0100980
981 if (!priv->link)
982 return -ENODEV;
983
984 id = (u16 *)malloc(ATA_ID_WORDS * 2);
985 if (!id) {
986 printf("Failed to malloc id data\n");
987 return -ENOMEM;
988 }
989
Stefan Roese05066202019-03-11 13:29:20 +0100990 mv_sata_identify(dev, port, id);
Tor Krill169789d2015-12-03 12:38:02 +0100991 ata_swap_buf_le16(id, ATA_ID_WORDS);
992#ifdef DEBUG
993 ata_dump_id(id);
994#endif
995
996 /* Serial number */
997 ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
Stefan Roese05066202019-03-11 13:29:20 +0100998 memcpy(desc->product, serial, sizeof(serial));
Tor Krill169789d2015-12-03 12:38:02 +0100999
1000 /* Firmware version */
1001 ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
Stefan Roese05066202019-03-11 13:29:20 +01001002 memcpy(desc->revision, firmware, sizeof(firmware));
Tor Krill169789d2015-12-03 12:38:02 +01001003
1004 /* Product model */
1005 ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
Stefan Roese05066202019-03-11 13:29:20 +01001006 memcpy(desc->vendor, product, sizeof(product));
Tor Krill169789d2015-12-03 12:38:02 +01001007
1008 /* Total sectors */
1009 n_sectors = ata_id_n_sectors(id);
Stefan Roese05066202019-03-11 13:29:20 +01001010 desc->lba = n_sectors;
Tor Krill169789d2015-12-03 12:38:02 +01001011
1012 /* Check if support LBA48 */
1013 if (ata_id_has_lba48(id)) {
Stefan Roese05066202019-03-11 13:29:20 +01001014 desc->lba48 = 1;
Tor Krill169789d2015-12-03 12:38:02 +01001015 debug("Device support LBA48\n");
1016 }
1017
1018 /* Get the NCQ queue depth from device */
1019 priv->queue_depth = ata_id_queue_depth(id);
1020
1021 /* Get the xfer mode from device */
Stefan Roese05066202019-03-11 13:29:20 +01001022 mv_sata_xfer_mode(dev, port, id);
Tor Krill169789d2015-12-03 12:38:02 +01001023
1024 /* Set the xfer mode to highest speed */
Stefan Roese05066202019-03-11 13:29:20 +01001025 mv_sata_set_features(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +01001026
1027 /* Start up */
Stefan Roese05066202019-03-11 13:29:20 +01001028 mv_start_edma_engine(dev, port);
Tor Krill169789d2015-12-03 12:38:02 +01001029
1030 return 0;
1031}
Stefan Roese05066202019-03-11 13:29:20 +01001032
1033static ulong sata_mv_read(struct udevice *blk, lbaint_t blknr,
1034 lbaint_t blkcnt, void *buffer)
1035{
Simon Glassc69cda22020-12-03 16:55:20 -07001036 struct mv_priv *priv = dev_get_plat(blk);
Stefan Roese05066202019-03-11 13:29:20 +01001037
1038 return ata_low_level_rw(blk, priv->dev_nr, blknr, blkcnt,
1039 buffer, READ_CMD);
1040}
1041
1042static ulong sata_mv_write(struct udevice *blk, lbaint_t blknr,
1043 lbaint_t blkcnt, const void *buffer)
1044{
Simon Glassc69cda22020-12-03 16:55:20 -07001045 struct mv_priv *priv = dev_get_plat(blk);
Stefan Roese05066202019-03-11 13:29:20 +01001046
1047 return ata_low_level_rw(blk, priv->dev_nr, blknr, blkcnt,
1048 (void *)buffer, WRITE_CMD);
1049}
1050
1051static const struct blk_ops sata_mv_blk_ops = {
1052 .read = sata_mv_read,
1053 .write = sata_mv_write,
1054};
1055
1056U_BOOT_DRIVER(sata_mv_driver) = {
1057 .name = "sata_mv_blk",
1058 .id = UCLASS_BLK,
1059 .ops = &sata_mv_blk_ops,
Simon Glasscaa4daa2020-12-03 16:55:18 -07001060 .plat_auto = sizeof(struct mv_priv),
Stefan Roese05066202019-03-11 13:29:20 +01001061};
1062
1063static int sata_mv_probe(struct udevice *dev)
1064{
1065 const void *blob = gd->fdt_blob;
1066 int node = dev_of_offset(dev);
1067 struct mv_priv *priv;
1068 struct udevice *blk;
1069 int nr_ports;
1070 int ret;
1071 int i;
Tony Dinh5df1ee42021-09-05 14:48:25 -07001072 int status = -ENODEV; /* If the probe fails to detected any SATA port */
Stefan Roese05066202019-03-11 13:29:20 +01001073
1074 /* Get number of ports of this SATA controller */
1075 nr_ports = min(fdtdec_get_int(blob, node, "nr-ports", -1),
1076 CONFIG_SYS_SATA_MAX_DEVICE);
1077
1078 for (i = 0; i < nr_ports; i++) {
1079 ret = blk_create_devicef(dev, "sata_mv_blk", "blk",
Bin Meng7020b2e2023-09-26 16:43:31 +08001080 UCLASS_AHCI, -1, DEFAULT_BLKSZ,
1081 0, &blk);
Stefan Roese05066202019-03-11 13:29:20 +01001082 if (ret) {
1083 debug("Can't create device\n");
Tony Dinh5df1ee42021-09-05 14:48:25 -07001084 continue;
Stefan Roese05066202019-03-11 13:29:20 +01001085 }
1086
Simon Glassc69cda22020-12-03 16:55:20 -07001087 priv = dev_get_plat(blk);
Stefan Roese05066202019-03-11 13:29:20 +01001088 priv->dev_nr = i;
1089
1090 /* Init SATA port */
1091 ret = sata_mv_init_sata(blk, i);
1092 if (ret) {
1093 debug("%s: Failed to init bus\n", __func__);
Tony Dinh5df1ee42021-09-05 14:48:25 -07001094 continue;
Stefan Roese05066202019-03-11 13:29:20 +01001095 }
1096
1097 /* Scan SATA port */
1098 ret = sata_mv_scan_sata(blk, i);
1099 if (ret) {
1100 debug("%s: Failed to scan bus\n", __func__);
Tony Dinh5df1ee42021-09-05 14:48:25 -07001101 continue;
Stefan Roese05066202019-03-11 13:29:20 +01001102 }
Tony Dinh5df1ee42021-09-05 14:48:25 -07001103
AKASHI Takahiroc662edd2022-03-08 20:36:43 +09001104 ret = blk_probe_or_unbind(dev);
1105 if (ret < 0)
1106 /* TODO: undo create */
1107 continue;
1108
Tony Dinh19acf772023-09-05 22:22:41 -07001109 ret = bootdev_setup_for_sibling_blk(blk, "sata_bootdev");
1110 if (ret) {
1111 printf("%s: Failed to create bootdev\n", __func__);
1112 continue;
1113 }
1114
Tony Dinh5df1ee42021-09-05 14:48:25 -07001115 /* If we got here, the current SATA port was probed
1116 * successfully, so set the probe status to successful.
1117 */
1118 status = 0;
Stefan Roese05066202019-03-11 13:29:20 +01001119 }
1120
Tony Dinh5df1ee42021-09-05 14:48:25 -07001121 return status;
Stefan Roese05066202019-03-11 13:29:20 +01001122}
1123
1124static int sata_mv_scan(struct udevice *dev)
1125{
1126 /* Nothing to do here */
Stefan Roese05066202019-03-11 13:29:20 +01001127 return 0;
1128}
1129
1130static const struct udevice_id sata_mv_ids[] = {
1131 { .compatible = "marvell,armada-370-sata" },
Michael Walle586f7b92019-04-03 23:28:30 +02001132 { .compatible = "marvell,orion-sata" },
Stefan Roese05066202019-03-11 13:29:20 +01001133 { }
1134};
1135
1136struct ahci_ops sata_mv_ahci_ops = {
1137 .scan = sata_mv_scan,
1138};
1139
1140U_BOOT_DRIVER(sata_mv_ahci) = {
1141 .name = "sata_mv_ahci",
1142 .id = UCLASS_AHCI,
1143 .of_match = sata_mv_ids,
1144 .ops = &sata_mv_ahci_ops,
1145 .probe = sata_mv_probe,
1146};