Re: EP93xx PIO IDE driver proposal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.

João Ramos wrote:

Ok, I've done the fixes you suggested and tested the patch.
It is working fine, and I'm sending you (once again) the patch attached to this e-mail.

In the meanwhile, I will post the entire patch to the 'arm-linux' mailing list, iterating untill I get a final patch for the platform dependent part.
Then, I will send the full patch back at linux-ide for submission.

I'm not sure why you again joined the driver patch and the platfrorm code patch together...

Ok, I will apply the changes, test them and then resubmit the final patch. By the way, I will submit the final patch through 'arm-linux' mailing list, if that is OK to you, since the full patch has platform-specific dependencies. I mean, as long as we iterate with the IDE part of it untill it is good for submission from you, I can submit it in 'arm-linux' with your acknowledge, right?

It is good to post it also to linux-arm for additional review & better merge coordination but the patch itself should go through IDE tree and linux-ide.

[ It is IDE host driver, has also IDE dependencies (ide_{set,get}_drivedata() patch) and there are some other pending IDE changes that will require minor
  updates to the patch. ]

Just ping me after platform-specific part is in and I'll push the driver to Linus (of course given that everybody is happy with the final version).

  I'm not happy yet. :-)

[...]

Add IDE host controller support for Cirrus Logic's EP93xx CPUs.

Signed-off-by: Joao Ramos <joao.ramos@xxxxxxx>
Cc: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
Cc: Ryan Mallon <ryan@xxxxxxxxxxxxxxxx>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@xxxxxxxxx>
Cc: Sergei Shtylyov <sshtylyov@xxxxxxxxxxxxxxxxx>

---

diff -urN linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/core.c linux-2.6.30-rc6/arch/arm/mach-ep93xx/core.c
--- linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/core.c	2009-05-16 05:12:57.000000000 +0100
+++ linux-2.6.30-rc6/arch/arm/mach-ep93xx/core.c	2009-05-19 16:03:36.000000000 +0100
@@ -537,6 +537,31 @@
 	platform_device_register(&ep93xx_i2c_device);
 }
+static struct resource ep93xx_ide_resources[] = {
+	{
+		.start	= EP93XX_IDE_PHYS_BASE,
+		.end	= EP93XX_IDE_PHYS_BASE + 0x37,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_EP93XX_EXT3,
+		.end	= IRQ_EP93XX_EXT3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ep93xx_ide_device = {
+	.name		= "ep93xx-ide",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(ep93xx_ide_resources),
+	.resource	= ep93xx_ide_resources,
+};
+
+void __init ep93xx_register_ide(void)
+{
+	platform_device_register(&ep93xx_ide_device);
+}
+
 extern void ep93xx_gpio_init(void);
void __init ep93xx_init_devices(void)
diff -urN linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h linux-2.6.30-rc6/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
--- linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h	2009-05-16 05:12:57.000000000 +0100
+++ linux-2.6.30-rc6/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h	2009-05-19 16:03:36.000000000 +0100
@@ -78,6 +78,7 @@
 #define EP93XX_BOOT_ROM_BASE		(EP93XX_AHB_VIRT_BASE + 0x00090000)
#define EP93XX_IDE_BASE (EP93XX_AHB_VIRT_BASE + 0x000a0000)
+#define EP93XX_IDE_PHYS_BASE		(EP93XX_AHB_PHYS_BASE + 0x000a0000)
#define EP93XX_VIC1_BASE (EP93XX_AHB_VIRT_BASE + 0x000b0000) diff -urN linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/include/mach/platform.h linux-2.6.30-rc6/arch/arm/mach-ep93xx/include/mach/platform.h
--- linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/include/mach/platform.h	2009-05-16 05:12:57.000000000 +0100
+++ linux-2.6.30-rc6/arch/arm/mach-ep93xx/include/mach/platform.h	2009-05-19 16:03:36.000000000 +0100
@@ -15,6 +15,7 @@
 void ep93xx_map_io(void);
 void ep93xx_init_irq(void);
 void ep93xx_init_time(unsigned long);
+void ep93xx_register_ide(void);
 void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
 void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
 void ep93xx_init_devices(void);
diff -urN linux-2.6.30-rc6.orig/drivers/ide/ep93xx-ide.c linux-2.6.30-rc6/drivers/ide/ep93xx-ide.c
--- linux-2.6.30-rc6.orig/drivers/ide/ep93xx-ide.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.30-rc6/drivers/ide/ep93xx-ide.c	2009-05-19 16:06:33.000000000 +0100
@@ -0,0 +1,521 @@
[...]
+static u16 __ep93xx_ide_read(void __iomem *base, unsigned long addr,
+		struct ide_timing *t)
+{
+	u32 reg;
+
+	reg = addr | IDECTRL_DIORN | IDECTRL_DIOWN;
+	writel(reg, base + IDECTRL);
+	ndelay(t->setup);
+
+	reg &= ~IDECTRL_DIORN;
+	writel(reg, base + IDECTRL);
+	ndelay(t->active);
+
+	while (!ep93xx_ide_check_iordy(base))
+		cpu_relax();
+
+	reg |= IDECTRL_DIORN;
+	writel(reg, base + IDECTRL);
+	ndelay(t->recover);

No, actually it should be t->cycle - t->active - t->setup. t->recover is a only a minimum recovery time, and you need to respect t->cycle minimum.

+static void __ep93xx_ide_write(void __iomem *base, u16 value,
+		unsigned long addr, struct ide_timing *t)
+{
+	u32 reg;
+
+	reg = addr | IDECTRL_DIORN | IDECTRL_DIOWN;
+	writel(reg, base + IDECTRL);
+	ndelay(t->setup);
+
+	writel(value, base + IDEDATAOUT);
+
+	reg &= ~IDECTRL_DIOWN;
+	writel(reg, base + IDECTRL);
+	ndelay(t->active);
+
+	while (!ep93xx_ide_check_iordy(base))
+		cpu_relax();
+
+	reg |= IDECTRL_DIOWN;
+	writel(reg, base + IDECTRL);
+	ndelay(t->recover);

  Same here...

+static void ep93xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+	ide_drive_t *pair = ide_get_pair_dev(drive);
+	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
+	struct ide_timing *cmd_t = t;
+	u32 reg = IDECFG_IDEEN | IDECFG_PIO;
+	void __iomem *base = drive->hwif->host->host_priv;
+
+	if (pair) {
+		struct ide_timing *pair_t = ide_get_drivedata(pair);
+
+		if (pair_t && pair_t->mode < t->mode)
+			cmd_t = pair_t;

  No, it should be like in other drivers:

       if (pair) {
<http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/ide/palm_bk3710.c;h=09d813d313f4a44986a2f358d8ddc08c619533f1;hb=HEAD#l169> u8 mode = ide_get_best_pio_mode(pair, 255, 4);

<http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/ide/palm_bk3710.c;h=09d813d313f4a44986a2f358d8ddc08c619533f1;hb=HEAD#l170> <http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/ide/palm_bk3710.c;h=09d813d313f4a44986a2f358d8ddc08c619533f1;hb=HEAD#l171> if (mode < pio) <http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/ide/palm_bk3710.c;h=09d813d313f4a44986a2f358d8ddc08c619533f1;hb=HEAD#l172> cmd_t = ide_timing_find_mode(XFER_PIO_0 + mode) ; <http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/ide/palm_bk3710.c;h=09d813d313f4a44986a2f358d8ddc08c619533f1;hb=HEAD#l173> }


+	}
+
+	/*
+	 * store the adequate PIO mode timings, to be used later
+	 * by ep93xx_ide_{read,write}
+	 */
+	ide_set_drivedata(drive, (void *)t);
+	ide_set_hwifdata(drive->hwif, (void *)cmd_t);
+
+	/* reconfigure IDE controller according to PIO mode */
+	switch (pio) {
+	case 4:
+		reg |= IDECFG_PIO_MODE_4 | ((1 << 8) & IDECFG_WST);

What does WST field mean? I also don't understand what purpose could serve setting the PIO mode here if you ensure to apply all the necessary manually...

+static struct ide_port_ops ep93xx_ide_port_ops = {
+	.set_pio_mode = ep93xx_ide_set_pio_mode,
+};
+
+static struct ide_port_info ep93xx_ide_port_info = {
+	.name		= MODULE_NAME,
+	.tp_ops 	= &ep93xx_ide_tp_ops,
+	.port_ops 	= &ep93xx_ide_port_ops,
+	.host_flags 	= IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |

 Is the latter really necessary?

+	/*
+	 * fill in ide_io_ports structure.
+	 * the device IDE register to be accessed is selected through
+	 * IDECTRL register's specific bitfields 'DA', 'CS1n' and 'CS0n':
+	 *   b4   b3   b2    b1     b0
+	 *   A2   A1   A0   CS1n   CS0n
+	 * the values filled in this structure allows the value to be directly
+	 * ORed to the IDECTRL register, hence giving directly the A[2:0] and
+	 * CS1n/CS0n values for each IDE register.
+	 * The values correspond to the transformation:
+	 *   ((real IDE address) << 2) | CS1n value << 1 | CS0n value
+	 */
+	hw.io_ports.data_addr = 0x02;
+	hw.io_ports.error_addr = 0x06;
+	hw.io_ports.nsect_addr = 0x0A;
+	hw.io_ports.lbal_addr = 0x0E;
+	hw.io_ports.lbam_addr = 0x12;
+	hw.io_ports.lbah_addr = 0x16;


  Hm, where's this empty line from? :-)

+	hw.io_ports.device_addr = 0x1A;
+	hw.io_ports.command_addr = 0x1E;
+	hw.io_ports.ctl_addr = 0x01;

MBR, Sergei


--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux