[U-Boot] [PATCH] BLOCK: Add freescale IMX51 PATA driver

Signed-off-by: Marek Vasut marek.vasut@gmail.com --- 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 marek.vasut@gmail.com + * + * Based on code by: + * Mahesh Mahadevan mahesh.mahadevan@freescale.com + * + * 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 <common.h> +#include <command.h> +#include <config.h> +#include <asm/byteorder.h> +#include <asm/io.h> +#include <ide.h> + +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> + +/* 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; +}

Dear Marek Vasut,
In message 1290810494-26936-1-git-send-email-marek.vasut@gmail.com you wrote:
Signed-off-by: Marek Vasut marek.vasut@gmail.com
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
...
+/* MXC ATA register offsets */ +enum {
- MXC_ATA_TIME_OFF = 0x00,
- MXC_ATA_TIME_ON = 0x01,
...
Please convert to a C struct.
Thanks.
Best regards,
Wolfgang Denk
participants (2)
-
Marek Vasut
-
Wolfgang Denk