Skip to contentSkip to conversation

libata: Cavium OCTEON SOC Compact Flash driver (v4)

PATCH In review David Daney 2 participants 6 messages Dec 9, 2008 – Dec 10, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover libata: Cavium OCTEON SOC Compact Flash driver (v4)

As part of our efforts to get the Cavium OCTEON processor support merged (see: http://marc.info/?l=linux-mips&m=122834773330212), we have this CF driver for your consideration.

This version is split into three separate patches. The first adds some entries to the ata_timing table in libata-core. The Second adds some special handling to ata_pio_need_iordy() for Compact Flash devices, The final patch is is the driver proper.

I will reply with the three patches.

David Daney (3):
libata: Add two more columns to the ata_timing table.
libata: Add special ata_pio_need_iordy() handling for Compact Flash.
libata: New driver for OCTEON SOC Compact Flash interface (v3).

 drivers/ata/Kconfig          |    9 +
 drivers/ata/Makefile         |    1 +
 drivers/ata/libata-core.c    |   78 ++--
 drivers/ata/pata_octeon_cf.c |  945 
++++++++++++++++++++++++++++++++++++++++++
 include/linux/libata.h       |   12 +-
 5 files changed, 1007 insertions(+), 38 deletions(-)
 create mode 100644 drivers/ata/pata_octeon_cf.c
#1 lore raw

PATCH 1/3 libata: Add two more columns to the ata_timing table.

The forthcoming OCTEON SOC Compact Flash driver needs a few more timing values than were available in the ata_timing table. I add new columns for write_hold and dmack_hold times. The values were obtained from the Compact Flash specification Rev 4.1.

---
 drivers/ata/libata-core.c |   74 +++++++++++++++++++++++---------------------
 include/linux/libata.h    |   12 +++++--
 2 files changed, 48 insertions(+), 38 deletions(-)
drivers/ata/libata-core.c +39 -35
index 5e2eb74..b156d83 100644
@@ -2953,33 +2953,33 @@ int sata_set_spd(struct ata_link *link)
  */
 
 static const struct ata_timing ata_timing[] = {
-/*	{ XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960,   0 }, */
-	{ XFER_PIO_0,     70, 290, 240, 600, 165, 150, 600,   0 },
-	{ XFER_PIO_1,     50, 290,  93, 383, 125, 100, 383,   0 },
-	{ XFER_PIO_2,     30, 290,  40, 330, 100,  90, 240,   0 },
-	{ XFER_PIO_3,     30,  80,  70, 180,  80,  70, 180,   0 },
-	{ XFER_PIO_4,     25,  70,  25, 120,  70,  25, 120,   0 },
-	{ XFER_PIO_5,     15,  65,  25, 100,  65,  25, 100,   0 },
-	{ XFER_PIO_6,     10,  55,  20,  80,  55,  20,  80,   0 },
-
-	{ XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 960,   0 },
-	{ XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 480,   0 },
-	{ XFER_SW_DMA_2,  60,   0,   0,   0, 120, 120, 240,   0 },
-
-	{ XFER_MW_DMA_0,  60,   0,   0,   0, 215, 215, 480,   0 },
-	{ XFER_MW_DMA_1,  45,   0,   0,   0,  80,  50, 150,   0 },
-	{ XFER_MW_DMA_2,  25,   0,   0,   0,  70,  25, 120,   0 },
-	{ XFER_MW_DMA_3,  25,   0,   0,   0,  65,  25, 100,   0 },
-	{ XFER_MW_DMA_4,  25,   0,   0,   0,  55,  20,  80,   0 },
-
-/*	{ XFER_UDMA_SLOW,  0,   0,   0,   0,   0,   0,   0, 150 }, */
-	{ XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
-	{ XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
-	{ XFER_UDMA_2,     0,   0,   0,   0,   0,   0,   0,  60 },
-	{ XFER_UDMA_3,     0,   0,   0,   0,   0,   0,   0,  45 },
-	{ XFER_UDMA_4,     0,   0,   0,   0,   0,   0,   0,  30 },
-	{ XFER_UDMA_5,     0,   0,   0,   0,   0,   0,   0,  20 },
-	{ XFER_UDMA_6,     0,   0,   0,   0,   0,   0,   0,  15 },
+/*	{ XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 30, 0, 960,   0 }, */
+	{ XFER_PIO_0,     70, 290, 240, 600, 165, 150, 30, 0, 600,   0 },
+	{ XFER_PIO_1,     50, 290,  93, 383, 125, 100, 20, 0, 383,   0 },
+	{ XFER_PIO_2,     30, 290,  40, 330, 100,  90, 15, 0, 240,   0 },
+	{ XFER_PIO_3,     30,  80,  70, 180,  80,  70, 10, 0, 180,   0 },
+	{ XFER_PIO_4,     25,  70,  25, 120,  70,  25, 10, 0, 120,   0 },
+	{ XFER_PIO_5,     15,  65,  25, 100,  65,  25,  5, 0, 100,   0 },
+	{ XFER_PIO_6,     10,  55,  20,  80,  55,  20,  5, 0,  80,   0 },
+
+	{ XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 30, 20, 960,   0 },
+	{ XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 30, 20, 480,   0 },
+	{ XFER_SW_DMA_2,  60,   0,   0,   0, 120, 120, 15, 20, 240,   0 },
+
+	{ XFER_MW_DMA_0,  60,   0,   0,   0, 215, 215, 20, 20, 480,   0 },
+	{ XFER_MW_DMA_1,  45,   0,   0,   0,  80,  50, 15, 5,  150,   0 },
+	{ XFER_MW_DMA_2,  25,   0,   0,   0,  70,  25, 10, 5,  120,   0 },
+	{ XFER_MW_DMA_3,  25,   0,   0,   0,  65,  25,  5, 5,  100,   0 },
+	{ XFER_MW_DMA_4,  25,   0,   0,   0,  55,  20,  5, 5,   80,   0 },
+
+/*	{ XFER_UDMA_SLOW,  0,   0,   0,   0,   0,   0,  0, 0,    0, 150 }, */
+	{ XFER_UDMA_0,     0,   0,   0,   0,   0,   0,  0, 0,    0, 120 },
+	{ XFER_UDMA_1,     0,   0,   0,   0,   0,   0,  0, 0,    0,  80 },
+	{ XFER_UDMA_2,     0,   0,   0,   0,   0,   0,  0, 0,    0,  60 },
+	{ XFER_UDMA_3,     0,   0,   0,   0,   0,   0,  0, 0,    0,  45 },
+	{ XFER_UDMA_4,     0,   0,   0,   0,   0,   0,  0, 0,    0,  30 },
+	{ XFER_UDMA_5,     0,   0,   0,   0,   0,   0,  0, 0,    0,  20 },
+	{ XFER_UDMA_6,     0,   0,   0,   0,   0,   0,  0, 0,    0,  15 },
 
 	{ 0xFF }
 };
@@ -2989,14 +2989,16 @@ static const struct ata_timing ata_timing[] = {
 
 static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT)
 {
-	q->setup   = EZ(t->setup   * 1000,  T);
-	q->act8b   = EZ(t->act8b   * 1000,  T);
-	q->rec8b   = EZ(t->rec8b   * 1000,  T);
-	q->cyc8b   = EZ(t->cyc8b   * 1000,  T);
-	q->active  = EZ(t->active  * 1000,  T);
-	q->recover = EZ(t->recover * 1000,  T);
-	q->cycle   = EZ(t->cycle   * 1000,  T);
-	q->udma    = EZ(t->udma    * 1000, UT);
+	q->setup	= EZ(t->setup      * 1000,  T);
+	q->act8b	= EZ(t->act8b      * 1000,  T);
+	q->rec8b	= EZ(t->rec8b      * 1000,  T);
+	q->cyc8b	= EZ(t->cyc8b      * 1000,  T);
+	q->active	= EZ(t->active     * 1000,  T);
+	q->recover	= EZ(t->recover    * 1000,  T);
+	q->write_hold	= EZ(t->write_hold * 1000,  T);
+	q->dmack_hold	= EZ(t->dmack_hold * 1000,  T);
+	q->cycle	= EZ(t->cycle      * 1000,  T);
+	q->udma		= EZ(t->udma       * 1000, UT);
 }
 
 void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
@@ -3008,6 +3010,8 @@ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
 	if (what & ATA_TIMING_CYC8B  ) m->cyc8b   = max(a->cyc8b,   b->cyc8b);
 	if (what & ATA_TIMING_ACTIVE ) m->active  = max(a->active,  b->active);
 	if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
+	if (what & ATA_TIMING_WRITE_HOLD) m->write_hold = max(a->write_hold, b->write_hold);
+	if (what & ATA_TIMING_DMACK_HOLD) m->dmack_hold = max(a->dmack_hold, b->dmack_hold);
 	if (what & ATA_TIMING_CYCLE  ) m->cycle   = max(a->cycle,   b->cycle);
 	if (what & ATA_TIMING_UDMA   ) m->udma    = max(a->udma,    b->udma);
 }
include/linux/libata.h +9 -3
index ed3f26e..649b323 100644
@@ -399,12 +399,16 @@ enum {
 				  ATA_TIMING_CYC8B,
 	ATA_TIMING_ACTIVE	= (1 << 4),
 	ATA_TIMING_RECOVER	= (1 << 5),
-	ATA_TIMING_CYCLE	= (1 << 6),
-	ATA_TIMING_UDMA		= (1 << 7),
+	ATA_TIMING_WRITE_HOLD	= (1 << 6),
+	ATA_TIMING_DMACK_HOLD	= (1 << 7),
+	ATA_TIMING_CYCLE	= (1 << 8),
+	ATA_TIMING_UDMA		= (1 << 9),
 	ATA_TIMING_ALL		= ATA_TIMING_SETUP | ATA_TIMING_ACT8B |
 				  ATA_TIMING_REC8B | ATA_TIMING_CYC8B |
 				  ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER |
-				  ATA_TIMING_CYCLE | ATA_TIMING_UDMA,
+				  ATA_TIMING_WRITE_HOLD |
+				  ATA_TIMING_DMACK_HOLD | ATA_TIMING_CYCLE |
+				  ATA_TIMING_UDMA,
 };
 
 enum ata_xfer_mask {
@@ -864,6 +868,8 @@ struct ata_timing {
 	unsigned short cyc8b;		/* t0 for 8-bit I/O */
 	unsigned short active;		/* t2 or tD */
 	unsigned short recover;		/* t2i or tK */
+	unsigned short write_hold;	/* t4 */
+	unsigned short dmack_hold;	/* tj */
 	unsigned short cycle;		/* t0 */
 	unsigned short udma;		/* t2CYCTYP/2 */
 };
Signature · 1 line
1.5.6.5
#2 lore raw

Re: [PATCH 1/3] libata: Add two more columns to the ata_timing table.

Hello.

Quoted 7 lines · David Daney

The forthcoming OCTEON SOC Compact Flash driver needs a few more timing values than were available in the ata_timing table. I add new columns for write_hold and dmack_hold times. The values were obtained from the Compact Flash specification Rev 4.1.

Well, you got it right except fot the SWDMA modes. :-)

Quoted 6 lines
drivers/ata/libata-core.c +0 -0
index 5e2eb74..b156d83 100644
@@ -2953,33 +2953,33 @@ int sata_set_spd(struct ata_link *link) 
 

[...]

drivers/ata/libata-core.c int sata_set_spd(struct ata_link *link) · line 2967

Quoted 4 lines
drivers/ata/libata-core.c +3 -0
+	{ XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 30, 20, 960,   0 },
+	{ XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 30, 20, 480,   0 },
+	{ XFER_SW_DMA_2,  60,   0,   0,   0, 120, 120, 15, 20, 240,   0 },

Well, I don't know what CF 4.1 has but ATA/ATA-2 have minimum -DIOx
to -DMACK hold time (tJ) for SW DMA modes always 0 ns, and -DIOW data hold time (tH) of 50, 30, and 20 for modes 0, 1, and 2 respectfully.

drivers/ata/libata-core.c struct ata_timing { · line 872

Quoted 6 lines
drivers/ata/libata-core.c +1 -0
@@ -864,6 +868,8 @@ struct ata_timing {
 	unsigned short cyc8b;		/* t0 for 8-bit I/O */
 	unsigned short active;		/* t2 or tD */
 	unsigned short recover;		/* t2i or tK */
+	unsigned short write_hold;	/* t4 */
 

The comment should be "t4 or tH", to be completely correct.

MBR, Sergei

#3 lore raw

Re: [PATCH 1/3] libata: Add two more columns to the ata_timing table.

Quoted 16 lines · Hello, I wrote:
Quoted 6 lines

timing values than were available in the ata_timing table. I add new columns for write_hold and dmack_hold times. The values were obtained from the Compact Flash specification Rev 4.1.

The forthcoming OCTEON SOC Compact Flash driver needs a few more

Well, you got it right except fot the SWDMA modes. :-)

Quoted 5 lines
drivers/ata/libata-core.c +0 -0
index 5e2eb74..b156d83 100644
@@ -2953,33 +2953,33 @@ int sata_set_spd(struct ata_link *link)   

[...]

Quoted 7 lines

drivers/ata/libata-core.c int sata_set_spd(struct ata_link *link) · line 2967

Quoted 4 lines
drivers/ata/libata-core.c +3 -0
+    { XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 30, 20, 960,   0 },
+    { XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 30, 20, 480,   0 },
+    { XFER_SW_DMA_2,  60,   0,   0,   0, 120, 120, 15, 20, 240,   0 },

Well, I don't know what CF 4.1 has but ATA/ATA-2 have minimum -DIOx
to -DMACK hold time (tJ) for SW DMA modes always 0 ns, and -DIOW data hold time (tH) of 50, 30, and 20 for modes 0, 1, and 2 respectfully.

Well, the correctness of these values shouldn't matter much because
IIRC libata have dropped support for SWDMA completely...

MBR, Sergei

#4 lore raw

PATCH 2/3 libata: Add special ata_pio_need_iordy() handling for Compact Flash.

In reply to David Daney

According to the Compact Flash specification r4.1, PIO modes 5 and 6 do not use iordy.

---
 drivers/ata/libata-core.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
drivers/ata/libata-core.c +4 -0
index b156d83..febdcb7 100644
@@ -1923,6 +1923,10 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
 	   as the caller should know this */
 	if (adev->link->ap->flags & ATA_FLAG_NO_IORDY)
 		return 0;
+	/* CF spec. r4.1 Table 22 says no iordy on PIO5 and PIO6.  */
+	if (ata_id_is_cfa(adev->id)
+	    && (adev->pio_mode == XFER_PIO_5 || adev->pio_mode == XFER_PIO_6))
+		return 0;
 	/* PIO3 and higher it is mandatory */
 	if (adev->pio_mode > XFER_PIO_2)
 		return 1;
Signature · 1 line
1.5.6.5
#5 lore raw

PATCH 3/3 libata: New driver for OCTEON SOC Compact Flash interface (v3).

In reply to David Daney

As part of our efforts to get the Cavium OCTEON processor support merged (see: http://marc.info/?l=linux-mips&m=122834773330212), we have this CF driver for your consideration.

Most OCTEON variants have *no* DMA or interrupt support on the CF interface so for these, only PIO is supported. Although if DMA is available, we do take advantage of it.

The register definitions are part of the chip support patch set mentioned above, and are not included here.

In this forth version, I have tried to address Sergei Shtylyov's comments reguarding the various timing parameters. .

Thanks,

---
 drivers/ata/Kconfig          |    9 +
 drivers/ata/Makefile         |    1 +
 drivers/ata/pata_octeon_cf.c |  945 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 955 insertions(+), 0 deletions(-)
 create mode 100644 drivers/ata/pata_octeon_cf.c
drivers/ata/Kconfig +9 -0
index 78fbec8..b59904b 100644
@@ -697,6 +697,15 @@ config PATA_IXP4XX_CF
 
 	  If unsure, say N.
 
+config PATA_OCTEON_CF
+	tristate "OCTEON Boot Bus Compact Flash support"
+	depends on CPU_CAVIUM_OCTEON
+	help
+	  This option enables a polled compact flash driver for use with
+	  compact flash cards attached to the OCTEON boot bus.
+
+	  If unsure, say N.
+
 config PATA_SCC
 	tristate "Toshiba's Cell Reference Set IDE support"
 	depends on PCI && PPC_CELLEB
drivers/ata/Makefile +1 -0
index 674965f..7f1ecf9 100644
@@ -69,6 +69,7 @@ obj-$(CONFIG_PATA_IXP4XX_CF)	+= pata_ixp4xx_cf.o
 obj-$(CONFIG_PATA_SCC)		+= pata_scc.o
 obj-$(CONFIG_PATA_SCH)		+= pata_sch.o
 obj-$(CONFIG_PATA_BF54X)	+= pata_bf54x.o
+obj-$(CONFIG_PATA_OCTEON_CF)	+= pata_octeon_cf.o
 obj-$(CONFIG_PATA_PLATFORM)	+= pata_platform.o
 obj-$(CONFIG_PATA_OF_PLATFORM)	+= pata_of_platform.o
 obj-$(CONFIG_PATA_ICSIDE)	+= pata_icside.o
drivers/ata/pata_octeon_cf.c new file +945 -0

945 lines not on this page · raw message

Signature · 1 line
1.5.6.5