]>
Commit | Line | Data |
---|---|---|
02a4b429 JJH |
1 | /* |
2 | * DWC SATA platform driver | |
3 | * | |
4 | * (C) Copyright 2016 | |
5 | * Texas Instruments Incorporated, <www.ti.com> | |
6 | * | |
7 | * Author: Mugunthan V N <mugunthanvnm@ti.com> | |
8 | * | |
9 | * SPDX-License-Identifier: GPL-2.0+ | |
10 | */ | |
11 | ||
12 | #include <common.h> | |
13 | #include <dm.h> | |
14 | #include <ahci.h> | |
15 | #include <scsi.h> | |
16 | #include <sata.h> | |
17 | #include <asm/arch/sata.h> | |
18 | #include <asm/io.h> | |
19 | #include <generic-phy.h> | |
20 | ||
21 | DECLARE_GLOBAL_DATA_PTR; | |
22 | ||
23 | struct dwc_ahci_priv { | |
24 | void *base; | |
25 | void *wrapper_base; | |
26 | }; | |
27 | ||
28 | static int dwc_ahci_ofdata_to_platdata(struct udevice *dev) | |
29 | { | |
30 | struct dwc_ahci_priv *priv = dev_get_priv(dev); | |
1dc64f6c | 31 | struct scsi_platdata *plat = dev_get_uclass_platdata(dev); |
02a4b429 JJH |
32 | fdt_addr_t addr; |
33 | ||
da409ccc SG |
34 | plat->max_id = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), |
35 | "max-id", CONFIG_SYS_SCSI_MAX_SCSI_ID); | |
36 | plat->max_lun = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), | |
02a4b429 JJH |
37 | "max-lun", CONFIG_SYS_SCSI_MAX_LUN); |
38 | ||
a821c4af | 39 | priv->base = map_physmem(devfdt_get_addr(dev), sizeof(void *), |
02a4b429 JJH |
40 | MAP_NOCACHE); |
41 | ||
a821c4af | 42 | addr = devfdt_get_addr_index(dev, 1); |
02a4b429 JJH |
43 | if (addr != FDT_ADDR_T_NONE) { |
44 | priv->wrapper_base = map_physmem(addr, sizeof(void *), | |
45 | MAP_NOCACHE); | |
46 | } else { | |
47 | priv->wrapper_base = NULL; | |
48 | } | |
49 | ||
50 | return 0; | |
51 | } | |
52 | ||
53 | static int dwc_ahci_probe(struct udevice *dev) | |
54 | { | |
55 | struct dwc_ahci_priv *priv = dev_get_priv(dev); | |
56 | int ret; | |
57 | struct phy phy; | |
58 | ||
59 | ret = generic_phy_get_by_name(dev, "sata-phy", &phy); | |
60 | if (ret) { | |
9b643e31 | 61 | pr_err("can't get the phy from DT\n"); |
02a4b429 JJH |
62 | return ret; |
63 | } | |
64 | ||
65 | ret = generic_phy_init(&phy); | |
66 | if (ret) { | |
9b643e31 | 67 | pr_err("unable to initialize the sata phy\n"); |
02a4b429 JJH |
68 | return ret; |
69 | } | |
70 | ||
71 | ret = generic_phy_power_on(&phy); | |
72 | if (ret) { | |
9b643e31 | 73 | pr_err("unable to power on the sata phy\n"); |
02a4b429 JJH |
74 | return ret; |
75 | } | |
76 | ||
77 | if (priv->wrapper_base) { | |
78 | u32 val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO; | |
79 | ||
80 | /* Enable SATA module, No Idle, No Standby */ | |
81 | writel(val, priv->wrapper_base + TI_SATA_SYSCONFIG); | |
82 | } | |
83 | ||
4279efc4 | 84 | ret = ahci_init_dm(dev, priv->base); |
7cf1afce SG |
85 | if (ret) |
86 | return ret; | |
87 | ||
e81589ea | 88 | return ahci_start_ports_dm(dev); |
02a4b429 JJH |
89 | } |
90 | ||
91 | static const struct udevice_id dwc_ahci_ids[] = { | |
92 | { .compatible = "snps,dwc-ahci" }, | |
93 | { } | |
94 | }; | |
95 | ||
96 | U_BOOT_DRIVER(dwc_ahci) = { | |
97 | .name = "dwc_ahci", | |
98 | .id = UCLASS_SCSI, | |
99 | .of_match = dwc_ahci_ids, | |
100 | .ofdata_to_platdata = dwc_ahci_ofdata_to_platdata, | |
f6ab5a92 | 101 | .ops = &scsi_ops, |
02a4b429 JJH |
102 | .probe = dwc_ahci_probe, |
103 | .priv_auto_alloc_size = sizeof(struct dwc_ahci_priv), | |
02a4b429 JJH |
104 | .flags = DM_FLAG_ALLOC_PRIV_DMA, |
105 | }; |