From e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb Mon Sep 17 00:00:00 2001 From: Yang Zhang Date: Fri, 28 Aug 2015 09:58:54 +0800 Subject: Add qemu 2.4.0 Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang --- qemu/roms/u-boot/drivers/block/mvsata_ide.c | 158 ++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 qemu/roms/u-boot/drivers/block/mvsata_ide.c (limited to 'qemu/roms/u-boot/drivers/block/mvsata_ide.c') diff --git a/qemu/roms/u-boot/drivers/block/mvsata_ide.c b/qemu/roms/u-boot/drivers/block/mvsata_ide.c new file mode 100644 index 000000000..574bc40b1 --- /dev/null +++ b/qemu/roms/u-boot/drivers/block/mvsata_ide.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD + * + * Written-by: Albert ARIBAUD + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#if defined(CONFIG_ORION5X) +#include +#elif defined(CONFIG_KIRKWOOD) +#include +#endif + +/* SATA port registers */ +struct mvsata_port_registers { + u32 reserved0[10]; + u32 edma_cmd; + u32 reserved1[181]; + /* offset 0x300 : ATA Interface registers */ + u32 sstatus; + u32 serror; + u32 scontrol; + u32 ltmode; + u32 phymode3; + u32 phymode4; + u32 reserved2[5]; + u32 phymode1; + u32 phymode2; + u32 bist_cr; + u32 bist_dw1; + u32 bist_dw2; + u32 serrorintrmask; +}; + +/* + * Sanity checks: + * - to compile at all, we need CONFIG_SYS_ATA_BASE_ADDR. + * - for ide_preinit to make sense, we need at least one of + * CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET; + * - for ide_preinit to be called, we need CONFIG_IDE_PREINIT. + * Fail with an explanation message if these conditions are not met. + * This is particularly important for CONFIG_IDE_PREINIT, because + * its lack would not cause a build error. + */ + +#if !defined(CONFIG_SYS_ATA_BASE_ADDR) +#error CONFIG_SYS_ATA_BASE_ADDR must be defined +#elif !defined(CONFIG_SYS_ATA_IDE0_OFFSET) \ + && !defined(CONFIG_SYS_ATA_IDE1_OFFSET) +#error CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET \ + must be defined +#elif !defined(CONFIG_IDE_PREINIT) +#error CONFIG_IDE_PREINIT must be defined +#endif + +/* + * Masks and values for SControl DETection and Interface Power Management, + * and for SStatus DETection. + */ + +#define MVSATA_EDMA_CMD_ATA_RST 0x00000004 +#define MVSATA_SCONTROL_DET_MASK 0x0000000F +#define MVSATA_SCONTROL_DET_NONE 0x00000000 +#define MVSATA_SCONTROL_DET_INIT 0x00000001 +#define MVSATA_SCONTROL_IPM_MASK 0x00000F00 +#define MVSATA_SCONTROL_IPM_NO_LP_ALLOWED 0x00000300 +#define MVSATA_SCONTROL_MASK \ + (MVSATA_SCONTROL_DET_MASK|MVSATA_SCONTROL_IPM_MASK) +#define MVSATA_PORT_INIT \ + (MVSATA_SCONTROL_DET_INIT|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED) +#define MVSATA_PORT_USE \ + (MVSATA_SCONTROL_DET_NONE|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED) +#define MVSATA_SSTATUS_DET_MASK 0x0000000F +#define MVSATA_SSTATUS_DET_DEVCOMM 0x00000003 + +/* + * Status codes to return to client callers. Currently, callers ignore + * exact value and only care for zero or nonzero, so no need to make this + * public, it is only #define'd for clarity. + * If/when standard negative codes are implemented in U-boot, then these + * #defines should be moved to, or replaced by ones from, the common list + * of status codes. + */ + +#define MVSATA_STATUS_OK 0 +#define MVSATA_STATUS_TIMEOUT -1 + +/* + * Initialize one MVSATAHC port: set SControl's IPM to "always active" + * and DET to "reset", then wait for SStatus's DET to become "device and + * comm ok" (or time out after 50 us if no device), then set SControl's + * DET back to "no action". + */ + +static int mvsata_ide_initialize_port(struct mvsata_port_registers *port) +{ + u32 control; + u32 status; + u32 timeleft = 10000; /* wait at most 10 ms for SATA reset to complete */ + + /* Hard reset */ + writel(MVSATA_EDMA_CMD_ATA_RST, &port->edma_cmd); + udelay(25); /* taken from original marvell port */ + writel(0, &port->edma_cmd); + + /* Set control IPM to 3 (no low power) and DET to 1 (initialize) */ + control = readl(&port->scontrol); + control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_INIT; + writel(control, &port->scontrol); + /* Toggle control DET back to 0 (normal operation) */ + control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_USE; + writel(control, &port->scontrol); + /* wait for status DET to become 3 (device and communication OK) */ + while (--timeleft) { + status = readl(&port->sstatus) & MVSATA_SSTATUS_DET_MASK; + if (status == MVSATA_SSTATUS_DET_DEVCOMM) + break; + udelay(1); + } + /* return success or time-out error depending on time left */ + if (!timeleft) + return MVSATA_STATUS_TIMEOUT; + return MVSATA_STATUS_OK; +} + +/* + * ide_preinit() will be called by ide_init in cmd_ide.c and will + * reset the MVSTATHC ports needed by the board. + */ + +int ide_preinit(void) +{ + int ret = MVSATA_STATUS_TIMEOUT; + int status; + + /* Enable ATA port 0 (could be SATA port 0 or 1) if declared */ +#if defined(CONFIG_SYS_ATA_IDE0_OFFSET) + status = mvsata_ide_initialize_port( + (struct mvsata_port_registers *) + (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE0_OFFSET)); + if (status == MVSATA_STATUS_OK) + ret = MVSATA_STATUS_OK; +#endif + /* Enable ATA port 1 (could be SATA port 0 or 1) if declared */ +#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) + status = mvsata_ide_initialize_port( + (struct mvsata_port_registers *) + (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE1_OFFSET)); + if (status == MVSATA_STATUS_OK) + ret = MVSATA_STATUS_OK; +#endif + /* Return success if at least one port initialization succeeded */ + return ret; +} -- cgit 1.2.3-korg