All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB"
@ 2011-01-24 12:47 Macpaul Lin
  2011-01-24 12:47 ` [U-Boot] [PATCH 2/2] ftide020: add faraday ide ahb controller from Linux kernel Macpaul Lin
  2011-04-11 20:26 ` [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB" Wolfgang Denk
  0 siblings, 2 replies; 5+ messages in thread
From: Macpaul Lin @ 2011-01-24 12:47 UTC (permalink / raw)
  To: u-boot

Although most IDE controller is designed to be connected to PCI bridge,
there are still some IDE controller support AHB interface for SoC design.

The driver implementation of these IDE-AHB controllers differ from other
IDE-PCI controller, some additional registers and commands access is required
during CMD/DATA I/O. Hence a configuration "CONFIG_IDE_AHB" in cmd_ide.c is
required to be defined to support these kinds of SoC controllers. Such as
Faraday's FTIDE020 series and Global Unichip's UINF-0301.

Signed-off-by: Macpaul Lin <macpaul@andestech.com>
---
 README           |    8 ++++++++
 common/cmd_ide.c |   37 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletions(-)

diff --git a/README b/README
index 727bf8a..3de0605 100644
--- a/README
+++ b/README
@@ -2673,6 +2673,14 @@ Low Level (hardware related) configuration options:
 		source code. It is used to make hardware dependant
 		initializations.
 
+- CONFIG_IDE_AHB:
+		Most IDE controllers were designed to be connected with PCI
+		interface. Only few of them were designed for AHB interface.
+		When software is doing ATA command and data transfer to
+		IDE devices through IDE-AHB controller, some additional
+		registers accessing to these kind of IDE-AHB controller
+		is requierd.
+
 - CONFIG_SYS_IMMR:	Physical address of the Internal Memory.
 		DO NOT CHANGE unless you know exactly what you're
 		doing! (11-4) [MPC8xx/82xx systems only]
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index ea0f4a7..edb4fc0 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -518,8 +518,22 @@ __ide_outb(int dev, int port, unsigned char val)
 {
 	debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
 		dev, port, val, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
+
+#if defined(CONFIG_IDE_AHB)
+	if (port) {
+		/* write command */
+		extern void ide_write_register(int, unsigned int, unsigned char);
+
+		ide_write_register(dev, port, val);
+	} else {
+		/* write data */
+		outb(val, (ATA_CURR_BASE(dev)));
+	}
+#else
 	outb(val, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
+#endif
 }
+
 void ide_outb (int dev, int port, unsigned char val)
 		__attribute__((weak, alias("__ide_outb")));
 
@@ -527,7 +541,15 @@ unsigned char inline
 __ide_inb(int dev, int port)
 {
 	uchar val;
+
+#if defined(CONFIG_IDE_AHB)
+	extern unsigned char ide_read_register(int, unsigned int);
+
+	val = ide_read_register(dev, port);
+#else
 	val = inb((ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
+#endif
+
 	debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
 		dev, port, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)), val);
 	return val;
@@ -696,6 +718,7 @@ void ide_init (void)
 		ide_dev_desc[i].blksz=0;
 		ide_dev_desc[i].lba=0;
 		ide_dev_desc[i].block_read=ide_read;
+		ide_dev_desc[i].block_write = ide_write;
 		if (!ide_bus_ok[IDE_BUS(i)])
 			continue;
 		ide_led (led, 1);		/* LED on	*/
@@ -902,7 +925,13 @@ output_data(int dev, ulong *sect_buf, int words)
 static void
 output_data(int dev, ulong *sect_buf, int words)
 {
-	outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words<<1);
+#if defined(CONFIG_IDE_AHB)
+	extern void ide_write_data(int, ulong *, int);
+
+	ide_write_data(dev, sect_buf, words);
+#else
+	outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
+#endif
 }
 #endif	/* CONFIG_IDE_SWAP_IO */
 
@@ -960,7 +989,13 @@ input_data(int dev, ulong *sect_buf, int words)
 static void
 input_data(int dev, ulong *sect_buf, int words)
 {
+#if defined(CONFIG_IDE_AHB)
+	extern void ide_read_data(int, ulong *, int);
+
+	ide_read_data(dev, sect_buf, words);
+#else
 	insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
+#endif
 }
 
 #endif	/* CONFIG_IDE_SWAP_IO */
-- 
1.7.3.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH 2/2] ftide020: add faraday ide ahb controller from Linux kernel
  2011-01-24 12:47 [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB" Macpaul Lin
@ 2011-01-24 12:47 ` Macpaul Lin
  2011-04-11 20:30   ` Wolfgang Denk
  2011-04-11 20:26 ` [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB" Wolfgang Denk
  1 sibling, 1 reply; 5+ messages in thread
From: Macpaul Lin @ 2011-01-24 12:47 UTC (permalink / raw)
  To: u-boot

Faraday's ftide020_s is an IDE-AHB controller for SoC design.
This patch ported the u-boot driver (PIO) of ftide020 ATA (IDE) driver
from Linux kernel. IDE commands include read, info, and other functions
has been implemented.

Because this IDE controller support AHB interface only which is differ
from other most IDE controller supports PCI interface. Some registers
access is required during CMD/DATA I/O. Hence a configuration
"CONFIG_IDE_AHB" is required to be defined according to the feature in
cmd_ide.c.

Signed-off-by: Macpaul Lin <macpaul@andestech.com>
---
 drivers/block/Makefile   |    1 +
 drivers/block/ftide020.c |  380 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/block/ftide020.h |  265 ++++++++++++++++++++++++++++++++
 3 files changed, 646 insertions(+), 0 deletions(-)
 create mode 100644 drivers/block/ftide020.c
 create mode 100644 drivers/block/ftide020.h

diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index e27175b..e3f46b8 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -28,6 +28,7 @@ LIB	:= $(obj)libblock.o
 COBJS-$(CONFIG_SCSI_AHCI) += ahci.o
 COBJS-$(CONFIG_ATA_PIIX) += ata_piix.o
 COBJS-$(CONFIG_FSL_SATA) += fsl_sata.o
+COBJS-$(CONFIG_IDE_FTIDE020) += ftide020.o
 COBJS-$(CONFIG_LIBATA) += libata.o
 COBJS-$(CONFIG_CMD_MG_DISK) += mg_disk.o
 COBJS-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
diff --git a/drivers/block/ftide020.c b/drivers/block/ftide020.c
new file mode 100644
index 0000000..eef8c08
--- /dev/null
+++ b/drivers/block/ftide020.c
@@ -0,0 +1,380 @@
+/*
+ * [origin: Linux kernel drivers/ide/ftide020.c]
+ * Faraday FTIDE020 ATA Controller (AHB)
+ *
+ * (C) Copyright 2011 Andes Technology
+ * Greentime Hu <greentime@andestech.com>
+ * Macpaul Lin <macpaul@andestech.com>
+ * Kuo-Wei Chou <kwchou@andestech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ *
+ */
+/* ftide020.c - ide support functions for the FTIDE020_S controller */
+
+#include <config.h>
+#include <common.h>
+#include <ata.h>
+#include <ide.h>
+#include <asm/io.h>
+#include <api_public.h>
+
+#include "ftide020.h"
+
+#define FTIDE_IP_NAME		"FTIDE020_S"
+#define FTIDE_DRIVER_VERSION	"1.0.1"
+
+#ifndef TRUE
+#define TRUE	1
+#endif
+
+#ifndef FALSE
+#define FALSE	0
+#endif
+
+/* DEBUG */
+#ifdef FTIDE_DEBUG
+	#define P_DEBUG(fmt, args...)	printf(FTIDE_IP_NAME ":" fmt, ## args)
+#else
+	#define P_DEBUG(a...)
+#endif
+
+/* base address */
+#define FTIDE_BASE	CONFIG_SYS_ATA_BASE_ADDR
+
+/*
+ * data address - The CMD and DATA use the same FIFO in FTIDE020_S
+ *   FTIDE_DATA = CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_DATA_OFFSET
+ *		= &ftide020->rw_fifo
+ */
+#define FTIDE_DATA	(&ftide020->rw_fifo)
+
+/* command and data I/O macros */
+/* 0x0 - DATA FIFO */
+#define WRITE_DATA(x)	outl((x), &ftide020->rw_fifo)	/* 0x00 */
+#define READ_DATA()	inl(&ftide020->rw_fifo)		/* 0x00 */
+/* 0x04 - R: Status Reg, W: CMD_FIFO */
+#define WRITE_CMD(x)	outl((x), &ftide020->cmd_fifo)	/* 0x04 */
+#define READ_STATUS()	inl(&ftide020->cmd_fifo)	/* 0x04 */
+
+#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); })
+
+void ftide_set_device(int cx8, int dev)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+
+	WRITE_CMD(SET_DEV_CMD | IDE_SET_CX8(cx8) | dev);
+}
+
+unsigned char ide_read_register(int dev, unsigned int port)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+
+	ftide_set_device(0, dev);
+	WRITE_CMD(READ_REG_CMD | IDE_REG_CS_READ(CONFIG_IDE_REG_CS) |
+		IDE_REG_DA_WRITE(port));
+
+	return READ_DATA() & 0xff;
+}
+
+void ide_write_register(int dev, unsigned int port, unsigned char val)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+
+	ftide_set_device(0, dev);
+	WRITE_CMD(WRITE_REG_CMD | IDE_REG_CS_WRITE(CONFIG_IDE_REG_CS) |
+		IDE_REG_DA_WRITE(port) | val);
+}
+
+void ide_write_data(int dev, ulong *sect_buf, int words)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+
+	ftide_set_device(0, dev);
+	WRITE_CMD(WRITE_DATA_CMD | ((words << 2) - 1));
+
+	/* block write */
+	outsl(FTIDE_DATA, sect_buf, words);
+}
+
+void ide_read_data(int dev, ulong *sect_buf, int words)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+
+	ftide_set_device(0, dev);
+	WRITE_CMD(READ_DATA_CMD | ((words << 2) - 1));
+
+	/* block read */
+	insl(FTIDE_DATA, sect_buf, words);
+}
+
+void ftide_dfifo_ready(ulong *time)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+
+	while (!(READ_STATUS() & STATUS_RFE)) {
+		if (*time-- == 0)
+			break;
+
+		udelay(100);
+	}
+}
+
+extern ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS];
+
+/* Reset_IDE_controller */
+static void reset_ide_controller(void)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+	unsigned int val;
+
+	val = inl(&ftide020->cr);
+
+	val |= CONTROL_RST;
+	outl(val, &ftide020->cr);
+
+	/* wait until reset OK, this is poor HW design */
+	mdelay(50);
+	val &= ~(CONTROL_RST);
+	outl(val, &ftide020->cr);
+
+	mdelay(50);
+	val |= CONTROL_SRST;
+	outl(val, &ftide020->cr);
+
+	/* wait until reset OK, this is poor HW design */
+	mdelay(50);
+	val &= ~(CONTROL_SRST);
+	outl(val, &ftide020->cr);
+
+	/* IORDY enable for PIO, for 2 device */
+	val |= (CONTROL_IRE0 | CONTROL_IRE1);
+	outl(val, &ftide020->cr);
+}
+
+/* IDE clock frequence */
+uint ftide_clock_freq(void)
+{
+	/*
+	 * todo: To aquire dynamic system frequency is dependend on the power
+	 * management unit which the ftide020 is connected to. In current,
+	 * there are only few PMU supports in u-boot.
+	 * So this function is wait for future enhancement.
+	 */
+	return 100;
+}
+
+/* Calculate Timing Registers */
+static unsigned int timing_cal(u16 t0, u16 t1, u16 t2, u16 t4)
+{
+	unsigned int val, ahb_ns = 8;
+	u8 TEOC, T1, T2, T4;
+
+	T1 = (u8) (t1 / ahb_ns);
+	if ((T1 * ahb_ns) == t1)
+		T1--;
+
+	T2 = (u8) (t2 / ahb_ns);
+	if ((T2 * ahb_ns) == t2)
+		T2--;
+
+	T4 = (u8) (t4 / ahb_ns);
+	if ((T4 * ahb_ns) == t4)
+		T4--;
+
+	TEOC = (u8) (t0 / ahb_ns);
+	if ((TEOC * ahb_ns) == t0)
+		TEOC--;
+
+	TEOC = ((TEOC > (T1 + T2 + T4)) ? (TEOC - (T1 + T2 + T4)) : 0);
+
+	/*
+	 * Here the fields in data timing registers in PIO mode
+	 * is accessed the same way as command timing registers.
+	 */
+	val =	DT_REG_PIO_T1(T1)	|
+		DT_REG_PIO_T2(T2)	|
+		DT_REG_PIO_T4(T4)	|
+		DT_REG_PIO_TEOC(TEOC);
+
+	return val;
+}
+
+/* Set Timing Register */
+static unsigned int set_mode_timing(u8 dev, u8 id, u8 mode)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+	u16 t0, t1, t2, t4;
+	u8 tcyc, tcvs, tmli, tenv, tack, trp;
+	unsigned int val, sysclk = 8;
+
+	if (id >= TATOL_TIMING)
+		return FALSE;
+
+	sysclk = ftide_clock_freq();
+	switch (id) {
+	case CMD_TIMING:
+		if (mode < REG_MODE) {
+			t0 = REG_ACCESS_TIMING[REG_T0][mode];
+			t1 = REG_ACCESS_TIMING[REG_T1][mode];
+			t2 = REG_ACCESS_TIMING[REG_T2][mode];
+			t4 = REG_ACCESS_TIMING[REG_T4][mode];
+
+			val = timing_cal(t0, t1, t2, t4);
+			outl(val, (dev ? &ftide020->ctrd1 : &ftide020->ctrd0));
+			return TRUE;
+		} else
+			return FALSE;
+	case PIO_TIMING:
+		if (mode < PIO_MODE) {
+			t0 = PIO_ACCESS_TIMING[PIO_T0][mode];
+			t1 = PIO_ACCESS_TIMING[PIO_T1][mode];
+			t2 = PIO_ACCESS_TIMING[PIO_T2][mode];
+			t4 = PIO_ACCESS_TIMING[PIO_T4][mode];
+
+			val = timing_cal(t0, t1, t2, t4);
+
+			outl(val, (dev ? &ftide020->dtrd1 : &ftide020->dtrd0));
+			return TRUE;
+		} else
+			return FALSE;
+	case DMA_TIMING:
+		if (mode < UDMA_MODE) {
+			/*
+			 * 0.999 is ceiling
+			 * for tcyc, tcvs, tmli, tenv, trp, tack
+			 */
+			tcyc = (u8) (((UDMA_ACCESS_TIMING[UDMA_TCYC][mode] * sysclk) + 9990) / 10000);
+			tcvs = (u8) (((UDMA_ACCESS_TIMING[UDMA_TCVS][mode] * sysclk) + 9990) / 10000);
+			tmli = (u8) (((UDMA_ACCESS_TIMING[UDMA_TMLI][mode] * sysclk) + 9990) / 10000);
+			tenv = (u8) (((UDMA_ACCESS_TIMING[UDMA_TENV][mode] * sysclk) + 9990) / 10000);
+			trp  = (u8) (((UDMA_ACCESS_TIMING[UDMA_TRP][mode]  * sysclk) + 9990) / 10000);
+			tack = (u8) (((UDMA_ACCESS_TIMING[UDMA_TACK][mode] * sysclk) + 9990) / 10000);
+
+			val  =	DT_REG_UDMA_TENV((tenv > 0) ? (tenv - 1) : 0) |
+				DT_REG_UDMA_TMLI((tmli > 0) ? (tmli - 1) : 0) |
+				DT_REG_UDMA_TCYC((tcyc > 0) ? (tcyc - 1) : 0) |
+				DT_REG_UDMA_TACK((tack > 0) ? (tack - 1) : 0) |
+				DT_REG_UDMA_TCVS((tcvs > 0) ? (tcvs - 1) : 0) |
+				DT_REG_UDMA_TRP((trp > 0) ? (trp - 1) : 0);
+
+			outl(val, (dev ? &ftide020->dtrd1 : &ftide020->dtrd0));
+			return TRUE;
+		} else
+			return FALSE;
+	default:
+		return FALSE;
+	}
+}
+
+static void ftide_read_hwrev(void)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+	unsigned int rev;
+
+	rev = inl(&ftide020->revision);
+}
+
+static int ftide_controller_probe(void)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+	unsigned int bak;
+
+	bak = inl(&ftide020->ctrd1);
+
+	/* probing by using shorter setup time */
+	outl(CONFIG_CTRD1_PROBE_T1, &ftide020->ctrd1);
+	if ((inl(&ftide020->ctrd1) & 0xff) != CONFIG_CTRD1_PROBE_T1) {
+		outl(bak, &ftide020->ctrd1);
+		return 0;
+	}
+
+	/* probing by using longer setup time */
+	outl(CONFIG_CTRD1_PROBE_T2, &ftide020->ctrd1);
+	if ((inl(&ftide020->ctrd1) & 0xff) != CONFIG_CTRD1_PROBE_T2) {
+		outl(bak, &ftide020->ctrd1);
+		return 0;
+	}
+
+	outl(bak, &ftide020->ctrd1);
+
+	return 1;
+}
+
+/* ide_preinit() was migrated from linux driver ide_probe_for_ftide() */
+int ide_preinit(void)
+{
+	static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
+	int status;
+	unsigned int val;
+	int i;
+
+	status = 1;
+	for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; i++)
+		ide_bus_offset[i] = -ATA_STATUS;
+
+	/* auto-detect IDE controller */
+	if (ftide_controller_probe()) {
+		printf("Faraday %s driver version %s\n", FTIDE_IP_NAME,
+		FTIDE_DRIVER_VERSION);
+	} else {
+		printf("Faraday ATA controller not found.\n");
+		return API_ENODEV;
+	}
+
+	/* check HW IP revision */
+	ftide_read_hwrev();
+
+	/* set FIFO threshold */
+	outl(((WRITE_FIFO - RX_THRESH) << 16) | RX_THRESH, &ftide020->dmatirr);
+
+	/* set Device_0 PIO_0 timing */
+	set_mode_timing(0, CMD_TIMING, REG_MODE0);
+	set_mode_timing(0, PIO_TIMING, PIO_MODE0);
+
+	/* set Device_1 PIO_0 timing */
+	set_mode_timing(1, CMD_TIMING, REG_MODE0);
+	set_mode_timing(1, PIO_TIMING, PIO_MODE0);
+
+	/* from E-bios */
+	/* little endian */
+	outl(0x0, &ftide020->cr);
+	mdelay(10);
+
+	outl(0x0fff0fff, &ftide020->ahbtr);
+	mdelay(10);
+
+	/* Enable controller Interrupt */
+	val = inl(&ftide020->cr);
+
+	/* Enable: IDE IRQ, IDE Terminate ERROR IRQ, AHB Timeout error IRQ */
+	val |= (CONTROL_IIE | CONTROL_TERIE | CONTROL_AERIE);
+	outl(val, &ftide020->cr);
+
+	status = 0;
+
+	return status;
+}
+
+void ide_set_reset(int flag)
+{
+	debug("ide_set_reset()\n");
+	reset_ide_controller();
+	return;
+}
diff --git a/drivers/block/ftide020.h b/drivers/block/ftide020.h
new file mode 100644
index 0000000..f3eefec
--- /dev/null
+++ b/drivers/block/ftide020.h
@@ -0,0 +1,265 @@
+/*
+ * Faraday FTIDE020_s ATA Controller (AHB)
+ *
+ * (C) Copyright 2011 Andes Technology
+ * Greentime Hu <greentime@andestech.com>
+ * Macpaul Lin <macpaul@andestech.com>
+ * Kuo-Wei Chou <kwchou@andestech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ *
+ */
+
+#ifndef __FTIDE020_H
+#define __FTIDE020_H
+
+/* ftide020.h - ide support functions for the FTIDE020_S controller */
+
+/* ATA controller register offset */
+struct ftide020_s {
+	unsigned int	rw_fifo;	/* 0x00 - READ/WRITE FIFO	*/
+	unsigned int	cmd_fifo;	/* 0x04 - R: Status Reg, W: CMD_FIFO */
+	unsigned int	cr;		/* 0x08 - Control Reg		*/
+	unsigned int	dmatirr;	/* 0x0c - DMA Threshold/Interrupt Reg */
+	unsigned int	ctrd0;		/* 0x10 - Command Timing Reg Device 0 */
+	unsigned int	dtrd0;		/* 0x14 - Data Timing Reg Device 0 */
+	unsigned int	ctrd1;		/* 0x18 - Command Timing Reg Device 1 */
+	unsigned int	dtrd1;		/* 0x1c - Data Timing Reg Device 1 */
+	unsigned int	ahbtr;		/* 0x20 - AHB Timeout Reg	*/
+	unsigned int	RESVD0;		/* 0x24 */
+	unsigned int	RESVD1;		/* 0x28 */
+	unsigned int	RESVD2;		/* 0x2c */
+	unsigned int	f_cfifo;	/* 0x30 - Feature Info of CMD_FIFO */
+	unsigned int	f_wfifo;	/* 0x34 - Feature Info of WRITE_FIFO */
+	unsigned int	f_rfifo;	/* 0x3c - Feature Info of READ_FIFO */
+	unsigned int	revision;	/* 0x38 - Revision No. of FTIDE020_S */
+};
+
+/* reference parameters */
+#define CONFIG_IDE_REG_CS	0x2	/* ref: ATA spec chaper 10, table 42 */
+#define CONFIG_CTRD1_PROBE_T1	0x2
+#define CONFIG_CTRD1_PROBE_T2	0x5
+
+/* status register - 0x04 */
+#define STATUS_CSEL		(1 << 0)	/* CSEL			*/
+#define STATUS_CS(x)		(((x) >> 1) & 0x3)	/* CS#[1:0]	*/
+#define STATUS_DMACK		(1 << 3)	/* DMACK#		*/
+#define STATUS_DMARQ		(1 << 4)	/* DMA req		*/
+#define STATUS_INTRQ		(1 << 5)	/* INT req		*/
+#define STATUS_DIOR		(1 << 6)	/* DIOR			*/
+#define STATUS_IORDY		(1 << 7)	/* I/O ready		*/
+#define STATUS_DIOW		(1 << 8)	/* DIOW#		*/
+#define STATUS_PDIAG		(1 << 9)	/* PDIAG		*/
+#define STATUS_DASP		(1 << 10)	/* DASP#		*/
+#define STATUS_DEV		(1 << 11)	/* selected device	*/
+#define STATUS_PIO		(1 << 12)	/* PIO in progress	*/
+#define STATUS_DMA		(1 << 13)	/* DMA in progress	*/
+#define STATUS_WFE		(1 << 14)	/* write fifo full	*/
+#define STATUS_RFE		(1 << 15)	/* read fifo empty	*/
+#define STATUS_COUNTER(x)	(((x) >> 16) & 0x3fff)	/* data tx counter */
+#define STATUS_ERR		(1 << 30)	/* trasfer terminated	*/
+#define STATUS_AER		(1 << 31)	/* AHB timeout indicate	*/
+
+/* Control register - 0x08 */
+#define CONTROL_TYPE_PIO	0x0
+#define CONTROL_TYPE_UDMA	0x1
+
+/* Device 0 */
+#define CONTROL_TYP0(x)		(((x) & 0x7) << 0)
+#define CONTROL_IRE0		(1 << 3)	/* Device 0 - enable IORDY for PIO */
+#define CONTROL_RESVD_DW0	(1 << 4)	/* Reserved - DW0 ?		*/
+#define CONTROL_E0		(1 << 5)	/* Device 0 - E0: 1: Big Endian	*/
+#define CONTROL_RESVD_WP0	(1 << 6)	/* Reserved - WP0 ?		*/
+#define CONTROL_RESVD_SE0	(1 << 7)	/* Reserved - SE0 ?		*/
+#define CONTROL_RESVD_ECC0	(1 << 8)	/* Reserved - ECC0 ?		*/
+
+#define CONTROL_RAEIE		(1 << 9)	/* IRQ - read fifo almost full	*/
+#define CONTROL_RNEIE		(1 << 10)	/* IRQ - read fifo not empty	*/
+#define CONTROL_WAFIE		(1 << 11)	/* IRQ - write fifo almost empty*/
+#define CONTROL_WNFIE		(1 << 12)	/* IRQ - write fifo not full	*/
+#define CONTROL_RESVD_FIRQ	(1 << 13)	/* RESERVED - FIRQ ?		*/
+#define CONTROL_AERIE		(1 << 14)	/* IRQ - AHB timeout error	*/
+#define CONTROL_IIE		(1 << 15)	/* IDE IRQ enable		*/
+
+/* Device 1 */
+#define CONTROL_TYP1(x)		(((x) & 0x7) << 16)
+#define CONTROL_IRE1		(1 << 19)	/* Device 1 - enable IORDY for PIO */
+#define CONTROL_RESVD_DW1	(1 << 20)	/* Reserved - DW1 ?		*/
+#define CONTROL_E1		(1 << 21)	/* Device 1 - E1: 1: Big Endian	*/
+#define CONTROL_RESVD_WP1	(1 << 22)	/* Reserved - WP1 ?		*/
+#define CONTROL_RESVD_SE1	(1 << 23)	/* Reserved - SE1 ?		*/
+#define CONTROL_RESVD_ECC1	(1 << 24)	/* Reserved - ECC1 ?		*/
+
+#define CONTROL_DRE		(1 << 25)	/* DMA receive enable		*/
+#define CONTROL_DTE		(1 << 26)	/* DMA transmit enable		*/
+#define CONTRIL_RESVD		(1 << 27)
+#define CONTROL_TERIE		(1 << 28)	/* transfer terminate error IRQ	*/
+#define CONTROL_T		(1 << 29)	/* terminate current operation	*/
+#define CONTROL_SRST		(1 << 30)	/* IDE soft reset		*/
+#define CONTROL_RST		(1 << 31)	/* IDE hardware reset		*/
+
+/* IRQ register - 0x0c */
+#define IRQ_RXTHRESH(x)		(((x) & 0x3ff) << 0)	/* Read FIFO threshold		*/
+#define IRQ_RFAEIRQ		(1 << 10)	/* Read FIFO almost full intr req	*/
+#define IRQ_RFNEIRQ		(1 << 11)	/* Read FIFO not empty intr req		*/
+#define IRQ_WFAFIRQ		(1 << 12)	/* Write FIFO almost empty intr req	*/
+#define IRQ_WFNFIRQ		(1 << 13)	/* Write FIFO not full intr req		*/
+#define IRQ_RESVD_FIRQ		(1 << 14)	/* Reserved - FIRQ ?			*/
+#define IRQ_IIRQ		(1 << 15)	/* IDE device interrupt request		*/
+#define IRQ_TXTHRESH(x)		(((x) & 0x3ff) << 16)	/* Write FIFO thershold		*/
+#define IRQ_TERMERR 		(1 << 28)	/* Transfer termination indication	*/
+#define IRQ_AHBERR 		(1 << 29)	/* AHB Timeout indication		*/
+
+/* Command Timing Register 0-1: ctrd (0x10, 0x18) */
+#define CT_REG_T1(x)		(((x) & 0xff) << 0)	/* the setup time of addressed	*/
+#define CT_REG_T2(x)		(((x) & 0xff) << 8)	/* the pluse width of DIOR/DIOW	*/
+#define CT_REG_T4(x)		(((x) & 0xff) << 16)	/* data hold time		*/
+#define CT_REG_TEOC(x)		(((x) & 0xff) << 24)	/* the time to the end of a cycle */
+
+/* Data Timing Register 0-1: dtrd (0x14, 0x1c) */
+#define DT_REG_PIO_T1(x)	(((x) & 0xff) << 0)	/* the setup time of addressed	*/
+#define DT_REG_PIO_T2(x)	(((x) & 0xff) << 8)	/* the pluse width of DIOR/DIOW	*/
+#define DT_REG_PIO_T4(x)	(((x) & 0xff) << 16)	/* data hold time		*/
+#define DT_REG_PIO_TEOC(x)	(((x) & 0xff) << 24)	/* the time to the end of a cycle */
+
+#define DT_REG_UDMA_TENV(x)	(((x) & 0xf) << 0)	/* the envelope time		*/
+#define DT_REG_UDMA_TMLI(x)	(((x) & 0xf) << 4)	/* interlock time		*/
+#define DT_REG_UDMA_TCYC(x)	(((x) & 0xff) << 8)	/* cycle time - data time	*/
+#define DT_REG_UDMA_TACK(x)	(((x) & 0xf) << 16)	/* the setup and hold time of DMACK */
+#define DT_REG_UDMA_TCVS(x)	(((x) & 0xf) << 20)	/* the setup tim eof CRC	*/
+#define DT_REG_UDMA_TRP(x)	(((x) & 0xff) << 24)	/* the time to ready to pause	*/
+
+/* ftide020_s command formats */
+/* read: IDE Register (CF1) */
+#define IDE_REG_OPCODE_READ	(1 << 13)		/* 0x2000 */
+#define IDE_REG_CS_READ(x)	(((x) & 0x3) << 11)
+#define IDE_REG_DA_READ(x)	(((x) & 0x7) << 8)
+#define IDE_REG_CMD_READ(x)	0x0			/* fixed value */
+
+/* write: IDE Register (CF2) */
+#define IDE_REG_OPCODE_WRITE	(0x5 << 13)		/* 0xA000 */
+#define IDE_REG_CS_WRITE(x)	(((x) & 0x3) << 11)
+#define IDE_REG_DA_WRITE(x)	(((x) & 0x7) << 8)
+#define IDE_REG_CMD_WRITE(x)	(((x) & 0xff) << 0)i	/* Actual ATA command or data */
+
+/* read/write data: PIO/UDMA (CF3) */
+#define IDE_DATA_WRITE		(1 << 15)		/* read: 0, write: 1 */
+#define IDE_DATA_OPCODE		(0x2 << 13)		/* device data access opcode */
+#define IDE_DATA_COUNTER(x)	(((x) & 0x1fff) << 0)	/* Number of transfers minus 1 */
+
+/* set device: (CF4) */
+#define IDE_SET_OPCODE		(0x2740 << 2) 		/* [15:2], 0x9d00 */
+/* CF3 counter value: 0: Tx in bytes, 1: in blocks (each block is 8 bytes) */
+#define IDE_SET_CX8(x)		(((x) & 0x1) << 1)
+#define IDE_SET_DEV(x)		(((x) & 0x1) << 0)	/* 0: Master, 1: Slave */
+
+/*
+ * IDE command bit definition
+ * This section is designed for minor hardware revision compatibility.
+ */
+#define READ_REG_CMD		IDE_REG_OPCODE_READ			/* 0x2000 */
+#define WRITE_REG_CMD		IDE_REG_OPCODE_WRITE			/* 0xA000 */
+#define READ_DATA_CMD		IDE_DATA_OPCODE				/* 0x4000 */
+#define WRITE_DATA_CMD		(IDE_DATA_OPCODE | IDE_DATA_WRITE)	/* 0xC000 */
+#define SET_DEV_CMD		IDE_SET_OPCODE				/* 0x9D00 */
+
+#define TATOL_TIMING		3
+#define CMD_TIMING		0
+#define PIO_TIMING		1
+#define DMA_TIMING		2
+
+/* Timing Parameters */
+/* Register Access Timing Parameters */
+#define REG_PARAMETER		4
+#define REG_T0			0
+#define REG_T1			1
+#define REG_T2			2
+#define REG_T4			3
+
+#define REG_MODE		5
+#define REG_MODE0		0
+#define REG_MODE1		1
+#define REG_MODE2		2
+#define REG_MODE3		3
+#define REG_MODE4		4
+
+/* PIO Access Timing Parameters */
+#define PIO_PARAMETER		4
+#define PIO_T0			0
+#define PIO_T1			1
+#define PIO_T2			2
+#define PIO_T4			3
+
+#define PIO_MODE		5
+#define PIO_MODE0		0
+#define PIO_MODE1		1
+#define PIO_MODE2		2
+#define PIO_MODE3		3
+#define PIO_MODE4		4
+
+/* UDMA Access Timing Parameters */
+#define UDMA_PARAMETER		6
+#define UDMA_TCYC		0
+#define UDMA_TCVS		1
+#define UDMA_TMLI		2
+#define UDMA_TENV		3
+#define UDMA_TRP		4
+#define UDMA_TACK		5
+
+#define UDMA_MODE 		7
+#define UDMA_MODE0		0
+#define UDMA_MODE1		1
+#define UDMA_MODE2		2
+#define UDMA_MODE3		3
+#define UDMA_MODE4		4
+#define UDMA_MODE5		5
+#define UDMA_MODE6		6
+
+/*
+ * RX_THRESH:
+ * hardware limitation: max = 8, should support 1,4,8,16,32,64,128,256
+ */
+#define RX_THRESH		8
+#define WRITE_FIFO		32	/* Hardwired value */
+
+/* Time Table */
+unsigned int REG_ACCESS_TIMING[REG_PARAMETER][REG_MODE] = {
+	{600,	383,	330,	180,	120},
+	{70,	50,	30,	30,	25},
+	{290,	290,	290,	80,	70},
+	{30,	20,	15,	10,	10},
+};
+
+unsigned int PIO_ACCESS_TIMING[PIO_PARAMETER][PIO_MODE] = {
+	{600,	383,	240,	180,	120},
+	{70,	50,	30,	30,	25},
+	{165,	125,	100,	80,	70},
+	{30,	20,	15,	10,	10},
+};
+
+unsigned int UDMA_ACCESS_TIMING[UDMA_PARAMETER][UDMA_MODE] = {
+	{1120,	730,	540,	390,	250,	168,	130}, /* 10X */
+	{700,	480,	310,	200,	67,	100,	100}, /* 10X */
+	{200,	200,	200,	200,	200,	200,	200}, /* 10X */
+	{200,	200,	200,	200,	200,	200,	200}, /* 10X */
+	{1600,	1250,	1000,	1000,	1000,	850,	850}, /* 10X */
+	{200,	200,	200,	200,	200,	200,	200}, /* 10X */
+};
+
+#endif /* __FTIDE020_H */
-- 
1.7.3.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB"
  2011-01-24 12:47 [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB" Macpaul Lin
  2011-01-24 12:47 ` [U-Boot] [PATCH 2/2] ftide020: add faraday ide ahb controller from Linux kernel Macpaul Lin
@ 2011-04-11 20:26 ` Wolfgang Denk
  2011-04-25 11:17   ` Macpaul Lin
  1 sibling, 1 reply; 5+ messages in thread
From: Wolfgang Denk @ 2011-04-11 20:26 UTC (permalink / raw)
  To: u-boot

Dear Macpaul Lin,

In message <1295873267-32570-1-git-send-email-macpaul@andestech.com> you wrote:
> Although most IDE controller is designed to be connected to PCI bridge,
> there are still some IDE controller support AHB interface for SoC design.
> 
> The driver implementation of these IDE-AHB controllers differ from other
> IDE-PCI controller, some additional registers and commands access is required
> during CMD/DATA I/O. Hence a configuration "CONFIG_IDE_AHB" in cmd_ide.c is
> required to be defined to support these kinds of SoC controllers. Such as
> Faraday's FTIDE020 series and Global Unichip's UINF-0301.
...
> +		extern void ide_write_register(int, unsigned int, unsigned char);
...
> +	extern unsigned char ide_read_register(int, unsigned int);

Etc.  Please move all such prototype decarations to an appropriate
header file and get rid of these "extern"s here.

Thanks.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
All a hacker needs is a tight PUSHJ, a loose pair of UUOs, and a warm
place to shift.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH 2/2] ftide020: add faraday ide ahb controller from Linux kernel
  2011-01-24 12:47 ` [U-Boot] [PATCH 2/2] ftide020: add faraday ide ahb controller from Linux kernel Macpaul Lin
@ 2011-04-11 20:30   ` Wolfgang Denk
  0 siblings, 0 replies; 5+ messages in thread
From: Wolfgang Denk @ 2011-04-11 20:30 UTC (permalink / raw)
  To: u-boot

Dear Macpaul Lin,

In message <1295873267-32570-2-git-send-email-macpaul@andestech.com> you wrote:
> Faraday's ftide020_s is an IDE-AHB controller for SoC design.
> This patch ported the u-boot driver (PIO) of ftide020 ATA (IDE) driver
> from Linux kernel. IDE commands include read, info, and other functions
> has been implemented.

When copying code from Linux, you must give exact reference from which
file and which exact version (commit ID) the code was taken rom;
please see bullet # 4 at
http://www.denx.de/wiki/view/U-Boot/Patches#Attributing_Code_Copyrights_Sign

...
> +extern ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS];

See before - please move to header file.

...
> +			tcyc = (u8) (((UDMA_ACCESS_TIMING[UDMA_TCYC][mode] * sysclk) + 9990) / 10000);
> +			tcvs = (u8) (((UDMA_ACCESS_TIMING[UDMA_TCVS][mode] * sysclk) + 9990) / 10000);
> +			tmli = (u8) (((UDMA_ACCESS_TIMING[UDMA_TMLI][mode] * sysclk) + 9990) / 10000);
> +			tenv = (u8) (((UDMA_ACCESS_TIMING[UDMA_TENV][mode] * sysclk) + 9990) / 10000);
> +			trp  = (u8) (((UDMA_ACCESS_TIMING[UDMA_TRP][mode]  * sysclk) + 9990) / 10000);
> +			tack = (u8) (((UDMA_ACCESS_TIMING[UDMA_TACK][mode] * sysclk) + 9990) / 10000);

Lines too long, please fix globally.

...
> +/* set device: (CF4) */
> +#define IDE_SET_OPCODE		(0x2740 << 2) 		/* [15:2], 0x9d00 */

please, no space before tabs. Please fix globally.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
When all is said and done, more is said than done.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB"
  2011-04-11 20:26 ` [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB" Wolfgang Denk
@ 2011-04-25 11:17   ` Macpaul Lin
  0 siblings, 0 replies; 5+ messages in thread
From: Macpaul Lin @ 2011-04-25 11:17 UTC (permalink / raw)
  To: u-boot

Hi Wolfgang,

2011/4/12 Wolfgang Denk <wd@denx.de>
>
> Dear Macpaul Lin,
> ...
> > + ? ? ? ? ? ? extern void ide_write_register(int, unsigned int, unsigned char);
> ...
> > + ? ? extern unsigned char ide_read_register(int, unsigned int);
>
> Etc. ?Please move all such prototype decarations to an appropriate
> header file and get rid of these "extern"s here.
>
> Thanks.
>
> Best regards,
>
> Wolfgang Denk

The patch v2 of this patch set has been send on?2011-04-12 as follows

cmd_ide: enhance new feature "CONFIG_IDE_AHB"
http://patchwork.ozlabs.org/patch/90723/

ftide020: add faraday ide ahb controller
http://patchwork.ozlabs.org/patch/90724/

Please help on checking if these 2 patch is adaptable.

Sorry for that at the time when I send patch v2,
I have no idea about how to send patch with correct "In-reply-to" header.

Thanks.

--
Best regards,
Macpaul Lin

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-04-25 11:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-24 12:47 [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB" Macpaul Lin
2011-01-24 12:47 ` [U-Boot] [PATCH 2/2] ftide020: add faraday ide ahb controller from Linux kernel Macpaul Lin
2011-04-11 20:30   ` Wolfgang Denk
2011-04-11 20:26 ` [U-Boot] [PATCH 1/2] cmd_ide: enhance new feature "CONFIG_IDE_AHB" Wolfgang Denk
2011-04-25 11:17   ` Macpaul Lin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.