diff options
author | Steven A. Falco | 2008-08-15 15:34:10 -0400 |
---|---|---|
committer | Wolfgang Denk | 2008-08-21 01:31:04 +0200 |
commit | 36c2d3062ecc6ab85f8e237180eb134464c48418 (patch) | |
tree | 67cfe217e923dab6797979aaffe39d4756dfd6ab | |
parent | 9571b84cb1423876f1153081b9e6a51d90fbcdc4 (diff) |
Add a hook to allow board-specific PIO mode setting.
This patch adds a hook whereby a board-specific routine can be called to
configure hardware for a PIO mode. The prototype for the board-specific
routine is:
int inline ide_set_piomode(int pio_mode)
ide_set_piomode should be prepared to configure hardware for a pio_mode
between 0 and 6, inclusive. It should return 0 on success or 1 on failure.
Signed-off-by: Steven A. Falco <sfalco@harris.com>
-rw-r--r-- | common/cmd_ide.c | 46 | ||||
-rw-r--r-- | include/ata.h | 4 |
2 files changed, 49 insertions, 1 deletions
diff --git a/common/cmd_ide.c b/common/cmd_ide.c index d6ba79f7040..069100700a8 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -543,6 +543,16 @@ __ide_inb(int dev, int port) unsigned char inline ide_inb(int dev, int port) __attribute__((weak, alias("__ide_inb"))); +#ifdef CONFIG_TUNE_PIO +int inline +__ide_set_piomode(int pio_mode) +{ + return 0; +} +int inline ide_set_piomode(int pio_mode) + __attribute__((weak, alias("__ide_set_piomode"))); +#endif + void ide_init (void) { @@ -1053,6 +1063,10 @@ static void ide_ident (block_dev_desc_t *dev_desc) int do_retry = 0; #endif +#ifdef CONFIG_TUNE_PIO + int pio_mode; +#endif + #if 0 int mode, cycle_time; #endif @@ -1168,6 +1182,38 @@ static void ide_ident (block_dev_desc_t *dev_desc) else dev_desc->removable = 0; +#ifdef CONFIG_TUNE_PIO + /* Mode 0 - 2 only, are directly determined by word 51. */ + pio_mode = iop->tPIO; + if (pio_mode > 2) { + printf("WARNING: Invalid PIO (word 51 = %d).\n", pio_mode); + pio_mode = 0; /* Force it to dead slow, and hope for the best... */ + } + + /* Any CompactFlash Storage Card that supports PIO mode 3 or above + * shall set bit 1 of word 53 to one and support the fields contained + * in words 64 through 70. + */ + if (iop->field_valid & 0x02) { + /* Mode 3 and above are possible. Check in order from slow + * to fast, so we wind up with the highest mode allowed. + */ + if (iop->eide_pio_modes & 0x01) + pio_mode = 3; + if (iop->eide_pio_modes & 0x02) + pio_mode = 4; + if (ata_id_is_cfa((u16 *)iop)) { + if ((iop->cf_advanced_caps & 0x07) == 0x01) + pio_mode = 5; + if ((iop->cf_advanced_caps & 0x07) == 0x02) + pio_mode = 6; + } + } + + /* System-specific, depends on bus speeds, etc. */ + ide_set_piomode(pio_mode); +#endif /* CONFIG_TUNE_PIO */ + #if 0 /* * Drive PIO mode autoselection diff --git a/include/ata.h b/include/ata.h index b669423bb0d..23967695890 100644 --- a/include/ata.h +++ b/include/ata.h @@ -236,7 +236,9 @@ typedef struct hd_driveid { unsigned short words130_155[26];/* reserved vendor words 130-155 */ unsigned short word156; unsigned short words157_159[3];/* reserved vendor words 157-159 */ - unsigned short words160_255[95];/* reserved words 160-255 */ + unsigned short words160_162[3];/* reserved words 160-162 */ + unsigned short cf_advanced_caps; + unsigned short words164_255[92];/* reserved words 164-255 */ } hd_driveid_t; |