#include <common.h>
#include <command.h>
+#include <dm.h>
#include <pci.h>
#include <asm/processor.h>
-#include <asm/errno.h>
+#include <linux/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <memalign.h>
#define WAIT_MS_FLUSH 5000
#define WAIT_MS_LINKUP 200
-static inline void __iomem *ahci_port_base(void __iomem *base, u32 port)
+__weak void __iomem *ahci_port_base(void __iomem *base, u32 port)
{
return base + 0x100 + (port * 0x80);
}
static int ahci_host_init(struct ahci_probe_ent *probe_ent)
{
-#ifndef CONFIG_SCSI_AHCI_PLAT
+#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
+# ifdef CONFIG_DM_PCI
+ struct udevice *dev = probe_ent->dev;
+ struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
+# else
pci_dev_t pdev = probe_ent->dev;
- u16 tmp16;
unsigned short vendor;
+# endif
+ u16 tmp16;
#endif
void __iomem *mmio = probe_ent->mmio_base;
u32 tmp, cap_save, cmd;
writel(cap_save, mmio + HOST_CAP);
writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
-#ifndef CONFIG_SCSI_AHCI_PLAT
+#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
+# ifdef CONFIG_DM_PCI
+ if (pplat->vendor == PCI_VENDOR_ID_INTEL) {
+ u16 tmp16;
+
+ dm_pci_read_config16(dev, 0x92, &tmp16);
+ dm_pci_write_config16(dev, 0x92, tmp16 | 0xf);
+ }
+# else
pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
if (vendor == PCI_VENDOR_ID_INTEL) {
tmp16 |= 0xf;
pci_write_config_word(pdev, 0x92, tmp16);
}
+# endif
#endif
probe_ent->cap = readl(mmio + HOST_CAP);
probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
tmp = readl(mmio + HOST_CTL);
debug("HOST_CTL 0x%x\n", tmp);
+#if !defined(CONFIG_DM_SCSI)
#ifndef CONFIG_SCSI_AHCI_PLAT
+# ifdef CONFIG_DM_PCI
+ dm_pci_read_config16(dev, PCI_COMMAND, &tmp16);
+ tmp |= PCI_COMMAND_MASTER;
+ dm_pci_write_config16(dev, PCI_COMMAND, tmp16);
+# else
pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
tmp |= PCI_COMMAND_MASTER;
pci_write_config_word(pdev, PCI_COMMAND, tmp16);
+# endif
+#endif
#endif
return 0;
}
static void ahci_print_info(struct ahci_probe_ent *probe_ent)
{
-#ifndef CONFIG_SCSI_AHCI_PLAT
+#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
+# if defined(CONFIG_DM_PCI)
+ struct udevice *dev = probe_ent->dev;
+# else
pci_dev_t pdev = probe_ent->dev;
+# endif
u16 cc;
#endif
void __iomem *mmio = probe_ent->mmio_base;
else
speed_s = "?";
-#ifdef CONFIG_SCSI_AHCI_PLAT
+#if defined(CONFIG_SCSI_AHCI_PLAT) || defined(CONFIG_DM_SCSI)
scc_s = "SATA";
#else
+# ifdef CONFIG_DM_PCI
+ dm_pci_read_config16(dev, 0x0a, &cc);
+# else
pci_read_config_word(pdev, 0x0a, &cc);
+# endif
if (cc == 0x0101)
scc_s = "IDE";
else if (cc == 0x0106)
}
#ifndef CONFIG_SCSI_AHCI_PLAT
-static int ahci_init_one(pci_dev_t pdev)
+# if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
+static int ahci_init_one(struct udevice *dev)
+# else
+static int ahci_init_one(pci_dev_t dev)
+# endif
{
+#if !defined(CONFIG_DM_SCSI)
u16 vendor;
+#endif
int rc;
probe_ent = malloc(sizeof(struct ahci_probe_ent));
}
memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
- probe_ent->dev = pdev;
+ probe_ent->dev = dev;
probe_ent->host_flags = ATA_FLAG_SATA
| ATA_FLAG_NO_LEGACY
probe_ent->pio_mask = 0x1f;
probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
- probe_ent->mmio_base = pci_map_bar(pdev, PCI_BASE_ADDRESS_5,
+#if !defined(CONFIG_DM_SCSI)
+#ifdef CONFIG_DM_PCI
+ probe_ent->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5,
+ PCI_REGION_MEM);
+
+ /* Take from kernel:
+ * JMicron-specific fixup:
+ * make sure we're in AHCI mode
+ */
+ dm_pci_read_config16(dev, PCI_VENDOR_ID, &vendor);
+ if (vendor == 0x197b)
+ dm_pci_write_config8(dev, 0x41, 0xa1);
+#else
+ probe_ent->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5,
PCI_REGION_MEM);
- debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
/* Take from kernel:
* JMicron-specific fixup:
* make sure we're in AHCI mode
*/
- pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
if (vendor == 0x197b)
- pci_write_config_byte(pdev, 0x41, 0xa1);
+ pci_write_config_byte(dev, 0x41, 0xa1);
+#endif
+#else
+ struct scsi_platdata *plat = dev_get_platdata(dev);
+ probe_ent->mmio_base = (void *)plat->base;
+#endif
+ debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
/* initialize adapter */
rc = ahci_host_init(probe_ent);
if (rc)
}
-
+#if defined(CONFIG_DM_SCSI)
+void scsi_low_level_init(int busdevfunc, struct udevice *dev)
+#else
void scsi_low_level_init(int busdevfunc)
+#endif
{
int i;
u32 linkmap;
#ifndef CONFIG_SCSI_AHCI_PLAT
+# if defined(CONFIG_DM_PCI)
+ struct udevice *dev;
+ int ret;
+
+ ret = dm_pci_bus_find_bdf(busdevfunc, &dev);
+ if (ret)
+ return;
+ ahci_init_one(dev);
+# elif defined(CONFIG_DM_SCSI)
+ ahci_init_one(dev);
+# else
ahci_init_one(busdevfunc);
+# endif
#endif
linkmap = probe_ent->link_port_map;
memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
ahci_fill_cmd_slot(pp, cmd_fis_len);
+ ahci_dcache_flush_sata_cmd(pp);
writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,