uboot/drivers/ata/dwc_ahci.c
<<
>>
Prefs
   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
  21DECLARE_GLOBAL_DATA_PTR;
  22
  23struct dwc_ahci_priv {
  24        void *base;
  25        void *wrapper_base;
  26};
  27
  28static int dwc_ahci_ofdata_to_platdata(struct udevice *dev)
  29{
  30        struct dwc_ahci_priv *priv = dev_get_priv(dev);
  31        struct scsi_platdata *plat = dev_get_uclass_platdata(dev);
  32        fdt_addr_t addr;
  33
  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),
  37                                        "max-lun", CONFIG_SYS_SCSI_MAX_LUN);
  38
  39        priv->base = map_physmem(devfdt_get_addr(dev), sizeof(void *),
  40                                 MAP_NOCACHE);
  41
  42        addr = devfdt_get_addr_index(dev, 1);
  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
  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) {
  61                pr_err("can't get the phy from DT\n");
  62                return ret;
  63        }
  64
  65        ret = generic_phy_init(&phy);
  66        if (ret) {
  67                pr_err("unable to initialize the sata phy\n");
  68                return ret;
  69        }
  70
  71        ret = generic_phy_power_on(&phy);
  72        if (ret) {
  73                pr_err("unable to power on the sata phy\n");
  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
  84        ret = ahci_init_dm(dev, priv->base);
  85        if (ret)
  86                return ret;
  87
  88        return ahci_start_ports_dm(dev);
  89}
  90
  91static const struct udevice_id dwc_ahci_ids[] = {
  92        { .compatible = "snps,dwc-ahci" },
  93        { }
  94};
  95
  96U_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,
 101        .ops    = &scsi_ops,
 102        .probe  = dwc_ahci_probe,
 103        .priv_auto_alloc_size = sizeof(struct dwc_ahci_priv),
 104        .flags = DM_FLAG_ALLOC_PRIV_DMA,
 105};
 106