1*693a1837SYifeng Zhao // SPDX-License-Identifier: GPL-2.0+
2f2105c61SSimon Glass /*
3f2105c61SSimon Glass * DWC SATA platform driver
4f2105c61SSimon Glass *
5f2105c61SSimon Glass * (C) Copyright 2016
6f2105c61SSimon Glass * Texas Instruments Incorporated, <www.ti.com>
7f2105c61SSimon Glass *
8f2105c61SSimon Glass * Author: Mugunthan V N <mugunthanvnm@ti.com>
9f2105c61SSimon Glass */
10f2105c61SSimon Glass
11f2105c61SSimon Glass #include <common.h>
12f2105c61SSimon Glass #include <dm.h>
13f2105c61SSimon Glass #include <ahci.h>
14f2105c61SSimon Glass #include <scsi.h>
15f2105c61SSimon Glass #include <sata.h>
16f2105c61SSimon Glass #include <asm/io.h>
17f2105c61SSimon Glass #include <generic-phy.h>
18f2105c61SSimon Glass
19f2105c61SSimon Glass struct dwc_ahci_priv {
20f2105c61SSimon Glass void *base;
21f2105c61SSimon Glass void *wrapper_base;
22f2105c61SSimon Glass };
23f2105c61SSimon Glass
dwc_ahci_bind(struct udevice * dev)24*693a1837SYifeng Zhao static int dwc_ahci_bind(struct udevice *dev)
25*693a1837SYifeng Zhao {
26*693a1837SYifeng Zhao struct udevice *scsi_dev;
27*693a1837SYifeng Zhao
28*693a1837SYifeng Zhao return ahci_bind_scsi(dev, &scsi_dev);
29*693a1837SYifeng Zhao }
30*693a1837SYifeng Zhao
dwc_ahci_ofdata_to_platdata(struct udevice * dev)31f2105c61SSimon Glass static int dwc_ahci_ofdata_to_platdata(struct udevice *dev)
32f2105c61SSimon Glass {
33f2105c61SSimon Glass struct dwc_ahci_priv *priv = dev_get_priv(dev);
34f2105c61SSimon Glass fdt_addr_t addr;
35f2105c61SSimon Glass
36*693a1837SYifeng Zhao priv->base = map_physmem(dev_read_addr(dev), sizeof(void *),
37f2105c61SSimon Glass MAP_NOCACHE);
38f2105c61SSimon Glass
39f2105c61SSimon Glass addr = devfdt_get_addr_index(dev, 1);
40f2105c61SSimon Glass if (addr != FDT_ADDR_T_NONE) {
41f2105c61SSimon Glass priv->wrapper_base = map_physmem(addr, sizeof(void *),
42f2105c61SSimon Glass MAP_NOCACHE);
43f2105c61SSimon Glass } else {
44f2105c61SSimon Glass priv->wrapper_base = NULL;
45f2105c61SSimon Glass }
46f2105c61SSimon Glass
47f2105c61SSimon Glass return 0;
48f2105c61SSimon Glass }
49f2105c61SSimon Glass
dwc_ahci_probe(struct udevice * dev)50f2105c61SSimon Glass static int dwc_ahci_probe(struct udevice *dev)
51f2105c61SSimon Glass {
52f2105c61SSimon Glass struct dwc_ahci_priv *priv = dev_get_priv(dev);
53f2105c61SSimon Glass int ret;
54f2105c61SSimon Glass struct phy phy;
55f2105c61SSimon Glass
56f2105c61SSimon Glass ret = generic_phy_get_by_name(dev, "sata-phy", &phy);
57f2105c61SSimon Glass if (ret) {
5890aa625cSMasahiro Yamada pr_err("can't get the phy from DT\n");
59f2105c61SSimon Glass return ret;
60f2105c61SSimon Glass }
61f2105c61SSimon Glass
62f2105c61SSimon Glass ret = generic_phy_init(&phy);
63f2105c61SSimon Glass if (ret) {
6490aa625cSMasahiro Yamada pr_err("unable to initialize the sata phy\n");
65f2105c61SSimon Glass return ret;
66f2105c61SSimon Glass }
67f2105c61SSimon Glass
68f2105c61SSimon Glass ret = generic_phy_power_on(&phy);
69f2105c61SSimon Glass if (ret) {
7090aa625cSMasahiro Yamada pr_err("unable to power on the sata phy\n");
71f2105c61SSimon Glass return ret;
72f2105c61SSimon Glass }
73f2105c61SSimon Glass
74*693a1837SYifeng Zhao return ahci_probe_scsi(dev, (ulong)priv->base);
75f2105c61SSimon Glass }
76f2105c61SSimon Glass
77f2105c61SSimon Glass static const struct udevice_id dwc_ahci_ids[] = {
78f2105c61SSimon Glass { .compatible = "snps,dwc-ahci" },
79f2105c61SSimon Glass { }
80f2105c61SSimon Glass };
81f2105c61SSimon Glass
82f2105c61SSimon Glass U_BOOT_DRIVER(dwc_ahci) = {
83f2105c61SSimon Glass .name = "dwc_ahci",
84*693a1837SYifeng Zhao .id = UCLASS_AHCI,
85f2105c61SSimon Glass .of_match = dwc_ahci_ids,
86*693a1837SYifeng Zhao .bind = dwc_ahci_bind,
87f2105c61SSimon Glass .ofdata_to_platdata = dwc_ahci_ofdata_to_platdata,
88f6ab5a92SSimon Glass .ops = &scsi_ops,
89f2105c61SSimon Glass .probe = dwc_ahci_probe,
90f2105c61SSimon Glass .priv_auto_alloc_size = sizeof(struct dwc_ahci_priv),
91f2105c61SSimon Glass };
92