xref: /openbmc/u-boot/drivers/ata/dwc_ahci.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
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