forked from MiCode/Xiaomi_Kernel_OpenSource
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
40 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/kk: 485efc6cf507eae2b8e83b56e179c8fa3980641a | ||
refs/heads/kk: 328dcbb63657ebbb2dd26982fa9e1fa9e04b6fa2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
/* | ||
* linux/drivers/ide/pci/siimage.c Version 1.12 Mar 10 2007 | ||
* linux/drivers/ide/pci/siimage.c Version 1.15 Jun 29 2007 | ||
* | ||
* Copyright (C) 2001-2002 Andre Hedrick <[email protected]> | ||
* Copyright (C) 2003 Red Hat <[email protected]> | ||
* Copyright (C) 2007 MontaVista Software, Inc. | ||
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz | ||
* | ||
* May be copied or modified under the terms of the GNU General Public License | ||
* | ||
|
@@ -31,6 +32,10 @@ | |
* unplugging/replugging the virtual CD interface when the DRAC is reset. | ||
* This often causes drivers/ide/siimage to panic but is ok with the rather | ||
* smarter code in libata. | ||
* | ||
* TODO: | ||
* - IORDY fixes | ||
* - VDMA support | ||
*/ | ||
|
||
#include <linux/types.h> | ||
|
@@ -160,82 +165,45 @@ static u8 sil_udma_filter(ide_drive_t *drive) | |
} | ||
|
||
/** | ||
* siimage_taskfile_timing - turn timing data to a mode | ||
* @hwif: interface to query | ||
* | ||
* Read the timing data for the interface and return the | ||
* mode that is being used. | ||
*/ | ||
|
||
static byte siimage_taskfile_timing (ide_hwif_t *hwif) | ||
{ | ||
u16 timing = 0x328a; | ||
unsigned long addr = siimage_selreg(hwif, 2); | ||
|
||
if (hwif->mmio) | ||
timing = hwif->INW(addr); | ||
else | ||
pci_read_config_word(hwif->pci_dev, addr, &timing); | ||
|
||
switch (timing) { | ||
case 0x10c1: return 4; | ||
case 0x10c3: return 3; | ||
case 0x1104: | ||
case 0x1281: return 2; | ||
case 0x2283: return 1; | ||
case 0x328a: | ||
default: return 0; | ||
} | ||
} | ||
|
||
/** | ||
* simmage_tuneproc - tune a drive | ||
* sil_tune_pio - tune a drive | ||
* @drive: drive to tune | ||
* @mode_wanted: the target operating mode | ||
* @pio: the desired PIO mode | ||
* | ||
* Load the timing settings for this device mode into the | ||
* controller. If we are in PIO mode 3 or 4 turn on IORDY | ||
* monitoring (bit 9). The TF timing is bits 31:16 | ||
*/ | ||
static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted) | ||
|
||
static void sil_tune_pio(ide_drive_t *drive, u8 pio) | ||
{ | ||
const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 }; | ||
const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; | ||
|
||
ide_hwif_t *hwif = HWIF(drive); | ||
ide_drive_t *pair = &hwif->drives[drive->dn ^ 1]; | ||
u32 speedt = 0; | ||
u16 speedp = 0; | ||
unsigned long addr = siimage_seldev(drive, 0x04); | ||
unsigned long tfaddr = siimage_selreg(hwif, 0x02); | ||
|
||
/* cheat for now and use the docs */ | ||
switch (mode_wanted) { | ||
case 4: | ||
speedp = 0x10c1; | ||
speedt = 0x10c1; | ||
break; | ||
case 3: | ||
speedp = 0x10c3; | ||
speedt = 0x10c3; | ||
break; | ||
case 2: | ||
speedp = 0x1104; | ||
speedt = 0x1281; | ||
break; | ||
case 1: | ||
speedp = 0x2283; | ||
speedt = 0x2283; | ||
break; | ||
case 0: | ||
default: | ||
speedp = 0x328a; | ||
speedt = 0x328a; | ||
break; | ||
u8 tf_pio = pio; | ||
|
||
/* trim *taskfile* PIO to the slowest of the master/slave */ | ||
if (pair->present) { | ||
u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4, NULL); | ||
|
||
if (pair_pio < tf_pio) | ||
tf_pio = pair_pio; | ||
} | ||
|
||
/* cheat for now and use the docs */ | ||
speedp = data_speed[pio]; | ||
speedt = tf_speed[tf_pio]; | ||
|
||
if (hwif->mmio) { | ||
hwif->OUTW(speedp, addr); | ||
hwif->OUTW(speedt, tfaddr); | ||
/* Now set up IORDY */ | ||
if(mode_wanted == 3 || mode_wanted == 4) | ||
if (pio > 2) | ||
hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2); | ||
else | ||
hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2); | ||
|
@@ -245,42 +213,17 @@ static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted) | |
pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp); | ||
speedp &= ~0x200; | ||
/* Set IORDY for mode 3 or 4 */ | ||
if(mode_wanted == 3 || mode_wanted == 4) | ||
if (pio > 2) | ||
speedp |= 0x200; | ||
pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp); | ||
} | ||
} | ||
|
||
/** | ||
* config_siimage_chipset_for_pio - set drive timings | ||
* @drive: drive to tune | ||
* @speed we want | ||
* | ||
* Compute the best pio mode we can for a given device. Also honour | ||
* the timings for the driver when dealing with mixed devices. Some | ||
* of this is ugly but its all wrapped up here | ||
* | ||
* The SI680 can also do VDMA - we need to start using that | ||
* | ||
* FIXME: we use the BIOS channel timings to avoid driving the task | ||
* files too fast at the disk. We need to compute the master/slave | ||
* drive PIO mode properly so that we can up the speed on a hotplug | ||
* system. | ||
*/ | ||
|
||
static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed) | ||
static void sil_tuneproc(ide_drive_t *drive, u8 pio) | ||
{ | ||
u8 channel_timings = siimage_taskfile_timing(HWIF(drive)); | ||
u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); | ||
|
||
/* WARNING PIO timing mess is going to happen b/w devices, argh */ | ||
if ((channel_timings != set_pio) && (set_pio > channel_timings)) | ||
set_pio = channel_timings; | ||
|
||
siimage_tuneproc(drive, set_pio); | ||
speed = XFER_PIO_0 + set_pio; | ||
if (set_speed) | ||
(void) ide_config_drive_speed(drive, speed); | ||
pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | ||
sil_tune_pio(drive, pio); | ||
(void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); | ||
} | ||
|
||
/** | ||
|
@@ -335,15 +278,14 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
case XFER_PIO_2: | ||
case XFER_PIO_1: | ||
case XFER_PIO_0: | ||
siimage_tuneproc(drive, (speed - XFER_PIO_0)); | ||
sil_tune_pio(drive, speed - XFER_PIO_0); | ||
mode |= ((unit) ? 0x10 : 0x01); | ||
break; | ||
case XFER_MW_DMA_2: | ||
case XFER_MW_DMA_1: | ||
case XFER_MW_DMA_0: | ||
multi = dma[speed - XFER_MW_DMA_0]; | ||
mode |= ((unit) ? 0x20 : 0x02); | ||
config_siimage_chipset_for_pio(drive, 0); | ||
break; | ||
case XFER_UDMA_6: | ||
case XFER_UDMA_5: | ||
|
@@ -356,7 +298,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) : | ||
(ultra5[speed - XFER_UDMA_0])); | ||
mode |= ((unit) ? 0x30 : 0x03); | ||
config_siimage_chipset_for_pio(drive, 0); | ||
break; | ||
default: | ||
return 1; | ||
|
@@ -390,7 +331,7 @@ static int siimage_config_drive_for_dma (ide_drive_t *drive) | |
return 0; | ||
|
||
if (ide_use_fast_pio(drive)) | ||
config_siimage_chipset_for_pio(drive, 1); | ||
sil_tuneproc(drive, 255); | ||
|
||
return -1; | ||
} | ||
|
@@ -961,7 +902,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) | |
|
||
hwif->resetproc = &siimage_reset; | ||
hwif->speedproc = &siimage_tune_chipset; | ||
hwif->tuneproc = &siimage_tuneproc; | ||
hwif->tuneproc = &sil_tuneproc; | ||
hwif->reset_poll = &siimage_reset_poll; | ||
hwif->pre_reset = &siimage_pre_reset; | ||
hwif->udma_filter = &sil_udma_filter; | ||
|
@@ -976,11 +917,11 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) | |
first = 0; | ||
} | ||
} | ||
if (!hwif->dma_base) { | ||
hwif->drives[0].autotune = 1; | ||
hwif->drives[1].autotune = 1; | ||
|
||
hwif->drives[0].autotune = hwif->drives[1].autotune = 1; | ||
|
||
if (hwif->dma_base == 0) | ||
return; | ||
} | ||
|
||
hwif->ultra_mask = 0x7f; | ||
hwif->mwdma_mask = 0x07; | ||
|