@ -7,6 +7,8 @@
# include <common.h>
# include <ahci.h>
# include <dm.h>
# include <dwc_ahsata.h>
# include <fis.h>
# include <libata.h>
# include <malloc.h>
@ -845,6 +847,7 @@ static ulong sata_write_common(struct ahci_uc_priv *uc_priv,
return rc ;
}
# if !CONFIG_IS_ENABLED(AHCI)
static int ahci_init_one ( int pdev )
{
int rc ;
@ -964,3 +967,113 @@ int scan_sata(int dev)
return dwc_ahsata_scan_common ( uc_priv , pdev ) ;
}
# endif /* CONFIG_IS_ENABLED(AHCI) */
# if CONFIG_IS_ENABLED(AHCI)
int dwc_ahsata_port_status ( struct udevice * dev , int port )
{
struct ahci_uc_priv * uc_priv = dev_get_uclass_priv ( dev ) ;
struct sata_port_regs * port_mmio ;
port_mmio = uc_priv - > port [ port ] . port_mmio ;
return readl ( & port_mmio - > ssts ) & SATA_PORT_SSTS_DET_MASK ? 0 : - ENXIO ;
}
int dwc_ahsata_bus_reset ( struct udevice * dev )
{
struct ahci_uc_priv * uc_priv = dev_get_uclass_priv ( dev ) ;
struct sata_host_regs * host_mmio = uc_priv - > mmio_base ;
setbits_le32 ( & host_mmio - > ghc , SATA_HOST_GHC_HR ) ;
while ( readl ( & host_mmio - > ghc ) & SATA_HOST_GHC_HR )
udelay ( 100 ) ;
return 0 ;
}
int dwc_ahsata_scan ( struct udevice * dev )
{
struct ahci_uc_priv * uc_priv = dev_get_uclass_priv ( dev ) ;
struct blk_desc * desc ;
struct udevice * blk ;
int ret ;
/*
* Create only one block device and do detection
* to make sure that there won ' t be a lot of
* block devices created
*/
device_find_first_child ( dev , & blk ) ;
if ( ! blk ) {
ret = blk_create_devicef ( dev , " dwc_ahsata_blk " , " blk " ,
IF_TYPE_SATA , - 1 , 512 , 0 , & blk ) ;
if ( ret ) {
debug ( " Can't create device \n " ) ;
return ret ;
}
}
desc = dev_get_uclass_platdata ( blk ) ;
ret = dwc_ahsata_scan_common ( uc_priv , desc ) ;
if ( ret ) {
debug ( " %s: Failed to scan bus \n " , __func__ ) ;
return ret ;
}
return 0 ;
}
int dwc_ahsata_probe ( struct udevice * dev )
{
struct ahci_uc_priv * uc_priv = dev_get_uclass_priv ( dev ) ;
int ret ;
uc_priv - > host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NO_ATAPI ;
uc_priv - > mmio_base = ( void __iomem * ) dev_read_addr ( dev ) ;
/* initialize adapter */
ret = ahci_host_init ( uc_priv ) ;
if ( ret )
return ret ;
ahci_print_info ( uc_priv ) ;
return dwc_ahci_start_ports ( uc_priv ) ;
}
static ulong dwc_ahsata_read ( struct udevice * blk , lbaint_t blknr ,
lbaint_t blkcnt , void * buffer )
{
struct blk_desc * desc = dev_get_uclass_platdata ( blk ) ;
struct udevice * dev = dev_get_parent ( blk ) ;
struct ahci_uc_priv * uc_priv ;
uc_priv = dev_get_uclass_priv ( dev ) ;
return sata_read_common ( uc_priv , desc , blknr , blkcnt , buffer ) ;
}
static ulong dwc_ahsata_write ( struct udevice * blk , lbaint_t blknr ,
lbaint_t blkcnt , const void * buffer )
{
struct blk_desc * desc = dev_get_uclass_platdata ( blk ) ;
struct udevice * dev = dev_get_parent ( blk ) ;
struct ahci_uc_priv * uc_priv ;
uc_priv = dev_get_uclass_priv ( dev ) ;
return sata_write_common ( uc_priv , desc , blknr , blkcnt , buffer ) ;
}
static const struct blk_ops dwc_ahsata_blk_ops = {
. read = dwc_ahsata_read ,
. write = dwc_ahsata_write ,
} ;
U_BOOT_DRIVER ( dwc_ahsata_blk ) = {
. name = " dwc_ahsata_blk " ,
. id = UCLASS_BLK ,
. ops = & dwc_ahsata_blk_ops ,
} ;
# endif