From patchwork Fri Nov 26 22:28:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 73247 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id DBD6EB70E8 for ; Sat, 27 Nov 2010 09:27:06 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 57BB228240; Fri, 26 Nov 2010 23:27:03 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cbzKEr0gnFUZ; Fri, 26 Nov 2010 23:27:03 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A509728231; Fri, 26 Nov 2010 23:27:01 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1EEBF28231 for ; Fri, 26 Nov 2010 23:26:59 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nO6EnnXSQOMp for ; Fri, 26 Nov 2010 23:26:57 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-fx0-f44.google.com (mail-fx0-f44.google.com [209.85.161.44]) by theia.denx.de (Postfix) with ESMTP id 0AA702822F for ; Fri, 26 Nov 2010 23:26:54 +0100 (CET) Received: by fxm9 with SMTP id 9so1925299fxm.3 for ; Fri, 26 Nov 2010 14:26:54 -0800 (PST) Received: by 10.223.123.142 with SMTP id p14mr2558578far.122.1290810414423; Fri, 26 Nov 2010 14:26:54 -0800 (PST) Received: from mashiro.kolej.mff.cuni.cz (vasut.kolej.mff.cuni.cz [78.128.198.52]) by mx.google.com with ESMTPS id n3sm267645fax.31.2010.11.26.14.26.52 (version=SSLv3 cipher=RC4-MD5); Fri, 26 Nov 2010 14:26:53 -0800 (PST) From: Marek Vasut To: u-boot@lists.denx.de Date: Fri, 26 Nov 2010 23:28:14 +0100 Message-Id: <1290810494-26936-1-git-send-email-marek.vasut@gmail.com> X-Mailer: git-send-email 1.7.2.3 Cc: mahesh.mahadevan@freescale.com Subject: [U-Boot] [PATCH] BLOCK: Add freescale IMX51 PATA driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Signed-off-by: Marek Vasut --- drivers/block/Makefile | 1 + drivers/block/mxc_ata.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 0 deletions(-) create mode 100644 drivers/block/mxc_ata.c diff --git a/drivers/block/Makefile b/drivers/block/Makefile index e27175b..aa7dc87 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -31,6 +31,7 @@ COBJS-$(CONFIG_FSL_SATA) += fsl_sata.o COBJS-$(CONFIG_LIBATA) += libata.o COBJS-$(CONFIG_CMD_MG_DISK) += mg_disk.o COBJS-$(CONFIG_MVSATA_IDE) += mvsata_ide.o +COBJS-$(CONFIG_MX51_PATA) += mxc_ata.o COBJS-$(CONFIG_PATA_BFIN) += pata_bfin.o COBJS-$(CONFIG_SATA_DWC) += sata_dwc.o COBJS-$(CONFIG_SATA_SIL3114) += sata_sil3114.o diff --git a/drivers/block/mxc_ata.c b/drivers/block/mxc_ata.c new file mode 100644 index 0000000..6f19e6f --- /dev/null +++ b/drivers/block/mxc_ata.c @@ -0,0 +1,139 @@ +/* + * Freescale iMX51 ATA driver + * + * Copyright (C) 2010 Marek Vasut + * + * Based on code by: + * Mahesh Mahadevan + * + * Based on code from original FSL ATA driver, which is + * part of eCos, the Embedded Configurable Operating System. + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* MXC ATA register offsets */ +enum { + MXC_ATA_TIME_OFF = 0x00, + MXC_ATA_TIME_ON = 0x01, + MXC_ATA_TIME_1 = 0x02, + MXC_ATA_TIME_2W = 0x03, + MXC_ATA_TIME_2R = 0x04, + MXC_ATA_TIME_AX = 0x05, + MXC_ATA_TIME_PIO_RDX = 0x06, + MXC_ATA_TIME_4 = 0x07, + MXC_ATA_TIME_9 = 0x08, + MXC_ATA_TIME_M = 0x09, + MXC_ATA_TIME_JN = 0x0a, + MXC_ATA_TIME_D = 0x0b, + MXC_ATA_TIME_K = 0x0c, + MXC_ATA_TIME_ACK = 0x0d, + MXC_ATA_TIME_ENV = 0x0e, + MXC_ATA_TIME_UDMA_RDX = 0x0f, + MXC_ATA_TIME_ZAH = 0x10, + MXC_ATA_TIME_MLIX = 0x11, + MXC_ATA_TIME_DVH = 0x12, + MXC_ATA_TIME_DZFS = 0x13, + MXC_ATA_TIME_DVS = 0x14, + MXC_ATA_TIME_CVH = 0x15, + MXC_ATA_TIME_SS = 0x16, + MXC_ATA_TIME_CYC = 0x17, + MXC_ATA_FIFO_DATA_16 = 0x1c, + MXC_ATA_FIFO_DATA_32 = 0x18, + MXC_ATA_FIFO_FILL = 0x20, + MXC_ATA_ATA_CONTROL = 0x24, + MXC_ATA_INTERRUPT_PENDING = 0x28, + MXC_ATA_INTERRUPT_ENABLE = 0x2c, + MXC_ATA_INTERRUPT_CLEAR = 0x30, + MXC_ATA_FIFO_ALARM = 0x34, + MXC_ATA_DRIVE_DATA = 0xa0, + MXC_ATA_DRIVE_FEATURES = 0xa4, + MXC_ATA_DRIVE_SECTOR_COUNT = 0xa8, + MXC_ATA_DRIVE_SECTOR_NUM = 0xac, + MXC_ATA_DRIVE_CYL_LOW = 0xb0, + MXC_ATA_DRIVE_CYL_HIGH = 0xb4, + MXC_ATA_DRIVE_DEV_HEAD = 0xb8, + MXC_ATA_COMMAND = 0xbc, + MXC_ATA_STATUS = 0xbc, + MXC_ATA_ALT_STATUS = 0xd8, +}; + +/* PIO timing table */ +#define NR_PIO_SPECS 5 +uint16_t pio_t0[NR_PIO_SPECS] = { 600, 383, 240, 180, 120 }; +uint16_t pio_t1[NR_PIO_SPECS] = { 70, 50, 30, 30, 25 }; +uint16_t pio_t2_8[NR_PIO_SPECS] = { 290, 290, 290, 80, 70 }; +uint16_t pio_t2_16[NR_PIO_SPECS] = { 165, 125, 100, 80, 70 }; +uint16_t pio_t2i[NR_PIO_SPECS] = { 40, 0, 0, 0, 0 }; +uint16_t pio_t4[NR_PIO_SPECS] = { 30, 20, 15, 10, 10 }; +uint16_t pio_t9[NR_PIO_SPECS] = { 20, 15, 10, 10, 10 }; +uint16_t pio_tA[NR_PIO_SPECS] = { 50, 50, 50, 50, 50 }; + +#define REG_TO_OFFSET(reg) ((reg & 0x3) * 8) +static void set_ata_bus_timing(unsigned char mode) +{ + uint32_t val; + uint32_t T = 1000000000 / mxc_get_clock(MXC_IPG_CLK); + + if (mode >= NR_PIO_SPECS) + return; + + /* Write TIME_OFF/ON/1/2W */ + val = (3 << REG_TO_OFFSET(MXC_ATA_TIME_OFF)) | + (3 << REG_TO_OFFSET(MXC_ATA_TIME_ON)) | + (((pio_t1[mode] + T) / T) << REG_TO_OFFSET(MXC_ATA_TIME_1)) | + (((pio_t2_8[mode] + T) / T) << REG_TO_OFFSET(MXC_ATA_TIME_2W)); + writel(val, MXC_ATA_TIME_OFF + CONFIG_SYS_ATA_BASE_ADDR); + + /* Write TIME_2R/AX/RDX/4 */ + val = (((pio_t2_8[mode] + T) / T) << REG_TO_OFFSET(MXC_ATA_TIME_2R)) | + (((pio_tA[mode] + T) / T + 2) << REG_TO_OFFSET(MXC_ATA_TIME_AX)) | + (1 << REG_TO_OFFSET(MXC_ATA_TIME_PIO_RDX)) | + (((pio_t4[mode] + T) / T) << REG_TO_OFFSET(MXC_ATA_TIME_4)); + writel(val, MXC_ATA_TIME_2R + CONFIG_SYS_ATA_BASE_ADDR); + + /* Write TIME_9 ; the rest of timing registers is irrelevant for PIO */ + val = (((pio_t9[mode] + T) / T) << REG_TO_OFFSET(MXC_ATA_TIME_9)); + writel(val, MXC_ATA_TIME_9 + CONFIG_SYS_ATA_BASE_ADDR); +} + +int ide_preinit(void) +{ + uint32_t ata_control = CONFIG_SYS_ATA_BASE_ADDR + MXC_ATA_ATA_CONTROL; + + /* 46.3.3.4 @ FSL iMX51 manual */ + writel(0x80, ata_control); /* FIFO normal op., drive reset */ + writel(0xc0, ata_control); /* FIFO normal op., drive not reset */ + + /* Configure the PIO timing */ + set_ata_bus_timing(CONFIG_MXC_ATA_PIO_MODE); + + /* 46.3.3.4 @ FSL iMX51 manual */ + writel(0x41, ata_control); /* Drive not reset, IORDY handshake */ + + return 0; +}