1*83d290c5STom Rini // 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/arch/sata.h>
17f2105c61SSimon Glass #include <asm/io.h>
18f2105c61SSimon Glass #include <generic-phy.h>
19f2105c61SSimon Glass
20f2105c61SSimon Glass struct dwc_ahci_priv {
21f2105c61SSimon Glass void *base;
22f2105c61SSimon Glass void *wrapper_base;
23f2105c61SSimon Glass };
24f2105c61SSimon Glass
dwc_ahci_bind(struct udevice * dev)2564563f53SJean-Jacques Hiblot static int dwc_ahci_bind(struct udevice *dev)
2664563f53SJean-Jacques Hiblot {
2764563f53SJean-Jacques Hiblot struct udevice *scsi_dev;
2864563f53SJean-Jacques Hiblot
2964563f53SJean-Jacques Hiblot return ahci_bind_scsi(dev, &scsi_dev);
3064563f53SJean-Jacques Hiblot }
3164563f53SJean-Jacques Hiblot
dwc_ahci_ofdata_to_platdata(struct udevice * dev)32f2105c61SSimon Glass static int dwc_ahci_ofdata_to_platdata(struct udevice *dev)
33f2105c61SSimon Glass {
34f2105c61SSimon Glass struct dwc_ahci_priv *priv = dev_get_priv(dev);
35f2105c61SSimon Glass fdt_addr_t addr;
36f2105c61SSimon Glass
37f2105c61SSimon Glass priv->base = map_physmem(devfdt_get_addr(dev), sizeof(void *),
38f2105c61SSimon Glass MAP_NOCACHE);
39f2105c61SSimon Glass
40f2105c61SSimon Glass addr = devfdt_get_addr_index(dev, 1);
41f2105c61SSimon Glass if (addr != FDT_ADDR_T_NONE) {
42f2105c61SSimon Glass priv->wrapper_base = map_physmem(addr, sizeof(void *),
43f2105c61SSimon Glass MAP_NOCACHE);
44f2105c61SSimon Glass } else {
45f2105c61SSimon Glass priv->wrapper_base = NULL;
46f2105c61SSimon Glass }
47f2105c61SSimon Glass
48f2105c61SSimon Glass return 0;
49f2105c61SSimon Glass }
50f2105c61SSimon Glass
dwc_ahci_probe(struct udevice * dev)51f2105c61SSimon Glass static int dwc_ahci_probe(struct udevice *dev)
52f2105c61SSimon Glass {
53f2105c61SSimon Glass struct dwc_ahci_priv *priv = dev_get_priv(dev);
54f2105c61SSimon Glass int ret;
55f2105c61SSimon Glass struct phy phy;
56f2105c61SSimon Glass
57f2105c61SSimon Glass ret = generic_phy_get_by_name(dev, "sata-phy", &phy);
58f2105c61SSimon Glass if (ret) {
599b643e31SMasahiro Yamada pr_err("can't get the phy from DT\n");
60f2105c61SSimon Glass return ret;
61f2105c61SSimon Glass }
62f2105c61SSimon Glass
63f2105c61SSimon Glass ret = generic_phy_init(&phy);
64f2105c61SSimon Glass if (ret) {
659b643e31SMasahiro Yamada pr_err("unable to initialize the sata phy\n");
66f2105c61SSimon Glass return ret;
67f2105c61SSimon Glass }
68f2105c61SSimon Glass
69f2105c61SSimon Glass ret = generic_phy_power_on(&phy);
70f2105c61SSimon Glass if (ret) {
719b643e31SMasahiro Yamada pr_err("unable to power on the sata phy\n");
72f2105c61SSimon Glass return ret;
73f2105c61SSimon Glass }
74f2105c61SSimon Glass
75f2105c61SSimon Glass if (priv->wrapper_base) {
76f2105c61SSimon Glass u32 val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO;
77f2105c61SSimon Glass
78f2105c61SSimon Glass /* Enable SATA module, No Idle, No Standby */
79f2105c61SSimon Glass writel(val, priv->wrapper_base + TI_SATA_SYSCONFIG);
80f2105c61SSimon Glass }
81f2105c61SSimon Glass
8264563f53SJean-Jacques Hiblot return ahci_probe_scsi(dev, (ulong)priv->base);
83f2105c61SSimon Glass }
84f2105c61SSimon Glass
85f2105c61SSimon Glass static const struct udevice_id dwc_ahci_ids[] = {
86f2105c61SSimon Glass { .compatible = "snps,dwc-ahci" },
87f2105c61SSimon Glass { }
88f2105c61SSimon Glass };
89f2105c61SSimon Glass
90f2105c61SSimon Glass U_BOOT_DRIVER(dwc_ahci) = {
91f2105c61SSimon Glass .name = "dwc_ahci",
9264563f53SJean-Jacques Hiblot .id = UCLASS_AHCI,
93f2105c61SSimon Glass .of_match = dwc_ahci_ids,
9464563f53SJean-Jacques Hiblot .bind = dwc_ahci_bind,
95f2105c61SSimon Glass .ofdata_to_platdata = dwc_ahci_ofdata_to_platdata,
96f6ab5a92SSimon Glass .ops = &scsi_ops,
97f2105c61SSimon Glass .probe = dwc_ahci_probe,
98f2105c61SSimon Glass .priv_auto_alloc_size = sizeof(struct dwc_ahci_priv),
99f2105c61SSimon Glass };
100