blob: 1dc91e7fce70c5957cec3b6ae9546d4d4d79fc58 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +02002/*
3 * DWC SATA platform driver
4 *
5 * (C) Copyright 2016
6 * Texas Instruments Incorporated, <www.ti.com>
7 *
8 * Author: Mugunthan V N <mugunthanvnm@ti.com>
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +02009 */
10
11#include <common.h>
12#include <dm.h>
13#include <ahci.h>
14#include <scsi.h>
15#include <sata.h>
Jonas Karlman7af66162023-07-22 14:02:12 +000016#ifdef CONFIG_ARCH_OMAP2PLUS
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020017#include <asm/arch/sata.h>
Jonas Karlman7af66162023-07-22 14:02:12 +000018#endif
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020019#include <asm/io.h>
20#include <generic-phy.h>
21
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020022struct dwc_ahci_priv {
23 void *base;
24 void *wrapper_base;
25};
26
Jean-Jacques Hiblot64563f52018-04-06 11:13:53 +020027static int dwc_ahci_bind(struct udevice *dev)
28{
29 struct udevice *scsi_dev;
30
31 return ahci_bind_scsi(dev, &scsi_dev);
32}
33
Simon Glassd1998a92020-12-03 16:55:21 -070034static int dwc_ahci_of_to_plat(struct udevice *dev)
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020035{
36 struct dwc_ahci_priv *priv = dev_get_priv(dev);
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020037 fdt_addr_t addr;
38
Masahiro Yamada25484932020-07-17 14:36:48 +090039 priv->base = map_physmem(dev_read_addr(dev), sizeof(void *),
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020040 MAP_NOCACHE);
41
Simon Glassa821c4a2017-05-17 17:18:05 -060042 addr = devfdt_get_addr_index(dev, 1);
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020043 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
53static 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) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +090061 pr_err("can't get the phy from DT\n");
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020062 return ret;
63 }
64
65 ret = generic_phy_init(&phy);
66 if (ret) {
Patrick Delaunayfc8ead12020-07-03 17:36:44 +020067 pr_debug("unable to initialize the sata phy\n");
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020068 return ret;
69 }
70
71 ret = generic_phy_power_on(&phy);
72 if (ret) {
Patrick Delaunayfc8ead12020-07-03 17:36:44 +020073 pr_debug("unable to power on the sata phy\n");
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020074 return ret;
75 }
76
Jonas Karlman7af66162023-07-22 14:02:12 +000077#ifdef CONFIG_ARCH_OMAP2PLUS
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020078 if (priv->wrapper_base) {
79 u32 val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO;
80
81 /* Enable SATA module, No Idle, No Standby */
82 writel(val, priv->wrapper_base + TI_SATA_SYSCONFIG);
83 }
Jonas Karlman7af66162023-07-22 14:02:12 +000084#endif
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020085
Jean-Jacques Hiblot64563f52018-04-06 11:13:53 +020086 return ahci_probe_scsi(dev, (ulong)priv->base);
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020087}
88
89static const struct udevice_id dwc_ahci_ids[] = {
90 { .compatible = "snps,dwc-ahci" },
91 { }
92};
93
94U_BOOT_DRIVER(dwc_ahci) = {
95 .name = "dwc_ahci",
Jean-Jacques Hiblot64563f52018-04-06 11:13:53 +020096 .id = UCLASS_AHCI,
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +020097 .of_match = dwc_ahci_ids,
Jean-Jacques Hiblot64563f52018-04-06 11:13:53 +020098 .bind = dwc_ahci_bind,
Simon Glassd1998a92020-12-03 16:55:21 -070099 .of_to_plat = dwc_ahci_of_to_plat,
Simon Glassf6ab5a92017-06-14 21:28:43 -0600100 .ops = &scsi_ops,
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +0200101 .probe = dwc_ahci_probe,
Simon Glass41575d82020-12-03 16:55:17 -0700102 .priv_auto = sizeof(struct dwc_ahci_priv),
Jean-Jacques Hiblot02a4b422017-04-24 11:51:31 +0200103};