]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
02a4b429 JJH |
2 | /* |
3 | * DWC SATA platform driver | |
4 | * | |
5 | * (C) Copyright 2016 | |
6 | * Texas Instruments Incorporated, <www.ti.com> | |
7 | * | |
8 | * Author: Mugunthan V N <[email protected]> | |
02a4b429 JJH |
9 | */ |
10 | ||
11 | #include <common.h> | |
12 | #include <dm.h> | |
13 | #include <ahci.h> | |
14 | #include <scsi.h> | |
15 | #include <sata.h> | |
7af6616c | 16 | #ifdef CONFIG_ARCH_OMAP2PLUS |
02a4b429 | 17 | #include <asm/arch/sata.h> |
7af6616c | 18 | #endif |
02a4b429 JJH |
19 | #include <asm/io.h> |
20 | #include <generic-phy.h> | |
1e94b46f | 21 | #include <linux/printk.h> |
02a4b429 | 22 | |
02a4b429 JJH |
23 | struct dwc_ahci_priv { |
24 | void *base; | |
25 | void *wrapper_base; | |
26 | }; | |
27 | ||
64563f53 JJH |
28 | static int dwc_ahci_bind(struct udevice *dev) |
29 | { | |
30 | struct udevice *scsi_dev; | |
31 | ||
32 | return ahci_bind_scsi(dev, &scsi_dev); | |
33 | } | |
34 | ||
d1998a9f | 35 | static int dwc_ahci_of_to_plat(struct udevice *dev) |
02a4b429 JJH |
36 | { |
37 | struct dwc_ahci_priv *priv = dev_get_priv(dev); | |
02a4b429 JJH |
38 | fdt_addr_t addr; |
39 | ||
2548493a | 40 | priv->base = map_physmem(dev_read_addr(dev), sizeof(void *), |
02a4b429 JJH |
41 | MAP_NOCACHE); |
42 | ||
a821c4af | 43 | addr = devfdt_get_addr_index(dev, 1); |
02a4b429 JJH |
44 | if (addr != FDT_ADDR_T_NONE) { |
45 | priv->wrapper_base = map_physmem(addr, sizeof(void *), | |
46 | MAP_NOCACHE); | |
47 | } else { | |
48 | priv->wrapper_base = NULL; | |
49 | } | |
50 | ||
51 | return 0; | |
52 | } | |
53 | ||
54 | static int dwc_ahci_probe(struct udevice *dev) | |
55 | { | |
56 | struct dwc_ahci_priv *priv = dev_get_priv(dev); | |
57 | int ret; | |
58 | struct phy phy; | |
59 | ||
60 | ret = generic_phy_get_by_name(dev, "sata-phy", &phy); | |
61 | if (ret) { | |
9b643e31 | 62 | pr_err("can't get the phy from DT\n"); |
02a4b429 JJH |
63 | return ret; |
64 | } | |
65 | ||
66 | ret = generic_phy_init(&phy); | |
67 | if (ret) { | |
fc8ead1a | 68 | pr_debug("unable to initialize the sata phy\n"); |
02a4b429 JJH |
69 | return ret; |
70 | } | |
71 | ||
72 | ret = generic_phy_power_on(&phy); | |
73 | if (ret) { | |
fc8ead1a | 74 | pr_debug("unable to power on the sata phy\n"); |
02a4b429 JJH |
75 | return ret; |
76 | } | |
77 | ||
7af6616c | 78 | #ifdef CONFIG_ARCH_OMAP2PLUS |
02a4b429 JJH |
79 | if (priv->wrapper_base) { |
80 | u32 val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO; | |
81 | ||
82 | /* Enable SATA module, No Idle, No Standby */ | |
83 | writel(val, priv->wrapper_base + TI_SATA_SYSCONFIG); | |
84 | } | |
7af6616c | 85 | #endif |
02a4b429 | 86 | |
64563f53 | 87 | return ahci_probe_scsi(dev, (ulong)priv->base); |
02a4b429 JJH |
88 | } |
89 | ||
90 | static const struct udevice_id dwc_ahci_ids[] = { | |
91 | { .compatible = "snps,dwc-ahci" }, | |
92 | { } | |
93 | }; | |
94 | ||
95 | U_BOOT_DRIVER(dwc_ahci) = { | |
96 | .name = "dwc_ahci", | |
64563f53 | 97 | .id = UCLASS_AHCI, |
02a4b429 | 98 | .of_match = dwc_ahci_ids, |
64563f53 | 99 | .bind = dwc_ahci_bind, |
d1998a9f | 100 | .of_to_plat = dwc_ahci_of_to_plat, |
f6ab5a92 | 101 | .ops = &scsi_ops, |
02a4b429 | 102 | .probe = dwc_ahci_probe, |
41575d8e | 103 | .priv_auto = sizeof(struct dwc_ahci_priv), |
02a4b429 | 104 | }; |