libata: Cavium OCTEON SOC Compact Flash driver (v4)
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
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
@@ -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
@@ -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
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_timingtable. I add new columns forwrite_holdanddmack_holdtimes. The values were obtained from the Compact Flash specification Rev 4.1.Signed-off-by David Daney <[email protected]>
Well, you got it right except fot the SWDMA modes. :-)
Quoted 6 lines
drivers/ata/libata-core.c +0
-0@@ -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
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_timingtable. I add new columns forwrite_holdanddmack_holdtimes. The values were obtained from the Compact Flash specification Rev 4.1.Signed-off-by David Daney <[email protected]>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@@ -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
PATCH 2/3 libata: Add special ata_pio_need_iordy() handling for Compact Flash.
In reply to David DaneyAccording 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
@@ -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
PATCH 3/3 libata: New driver for OCTEON SOC Compact Flash interface (v3).
In reply to David DaneyAs 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
@@ -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
@@ -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