/*
- * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008,2010 Freescale Semiconductor, Inc.
* Dave Liu <daveliu@freescale.com>
*
* This program is free software; you can redistribute it and/or
#include <command.h>
#include <asm/io.h>
#include <asm/processor.h>
+#include <asm/fsl_serdes.h>
#include <malloc.h>
#include <libata.h>
#include <fis.h>
#endif
};
-static inline void mdelay(unsigned long msec)
-{
- unsigned long i;
- for (i = 0; i < msec; i++)
- udelay(1000);
-}
-
static inline void sdelay(unsigned long sec)
{
unsigned long i;
return -1;
}
+#ifdef CONFIG_MPC85xx
+ if ((dev == 0) && (!is_serdes_configured(SATA1))) {
+ printf("SATA%d [dev = %d] is not enabled\n", dev+1, dev);
+ return -1;
+ }
+ if ((dev == 1) && (!is_serdes_configured(SATA2))) {
+ printf("SATA%d [dev = %d] is not enabled\n", dev+1, dev);
+ return -1;
+ }
+#endif
+
/* Allocate SATA device driver struct */
sata = (fsl_sata_t *)malloc(sizeof(fsl_sata_t));
if (!sata) {
/* Wait the controller offline */
ata_wait_register(®->hstatus, HSTATUS_ONOFF, 0, 1000);
-#if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001)
- /*
- * For P1022/1013 Rev1.0 silicon, after power on SATA host
- * controller is configured in legacy mode instead of the
- * expected enterprise mode. software needs to clear bit[28]
- * of HControl register to change to enterprise mode from
- * legacy mode.
- */
- {
- u32 svr = get_svr();
- if (IS_SVR_REV(svr, 1, 0) &&
- ((SVR_SOC_VER(svr) == SVR_P1022) ||
- (SVR_SOC_VER(svr) == SVR_P1022_E) ||
- (SVR_SOC_VER(svr) == SVR_P1013) ||
- (SVR_SOC_VER(svr) == SVR_P1013_E))) {
- out_le32(®->hstatus, 0x20000000);
- out_le32(®->hcontrol, 0x00000100);
- }
- }
-#endif
-
/* Set the command header base address to CHBA register to tell DMA */
out_le32(®->chba, (u32)cmd_hdr & ~0x3);
int ncq_channel;
u64 block;
- if (sata_dev_desc[dev].lba48 != 1) {
+ if (sata->lba48 != 1) {
printf("execute FPDMA command on non-LBA48 hard disk\n\r");
return -1;
}
ulong sata_read(int dev, u32 blknr, u32 blkcnt, void *buffer)
{
u32 rc;
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
- if (sata_dev_desc[dev].lba48)
+ if (sata->lba48)
rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, READ_CMD);
else
rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, READ_CMD);
ulong sata_write(int dev, u32 blknr, u32 blkcnt, void *buffer)
{
u32 rc;
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
- if (sata_dev_desc[dev].lba48) {
+ if (sata->lba48) {
rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, WRITE_CMD);
if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush_ext(dev))
fsl_sata_flush_cache_ext(dev);
n_sectors = ata_id_n_sectors(id);
sata_dev_desc[dev].lba = (u32)n_sectors;
+#ifdef CONFIG_LBA48
/* Check if support LBA48 */
if (ata_id_has_lba48(id)) {
- sata_dev_desc[dev].lba48 = 1;
+ sata->lba48 = 1;
debug("Device support LBA48\n\r");
- }
+ } else
+ debug("Device supports LBA28\n\r");
+#endif
/* Get the NCQ queue depth from device */
sata->queue_depth = ata_id_queue_depth(id);