diff options
| -rw-r--r-- | drivers/ide/pci/opti621.c | 92 |
1 files changed, 15 insertions, 77 deletions
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index c746e6f06077..8c715b7a85db 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c | |||
| @@ -81,8 +81,6 @@ | |||
| 81 | * 0.5 doesn't work. | 81 | * 0.5 doesn't work. |
| 82 | */ | 82 | */ |
| 83 | 83 | ||
| 84 | #define OPTI621_DEBUG /* define for debug messages */ | ||
| 85 | |||
| 86 | #include <linux/types.h> | 84 | #include <linux/types.h> |
| 87 | #include <linux/module.h> | 85 | #include <linux/module.h> |
| 88 | #include <linux/kernel.h> | 86 | #include <linux/kernel.h> |
| @@ -110,23 +108,8 @@ | |||
| 110 | 108 | ||
| 111 | static int reg_base; | 109 | static int reg_base; |
| 112 | 110 | ||
| 113 | #define PIO_NOT_EXIST 254 | ||
| 114 | #define PIO_DONT_KNOW 255 | ||
| 115 | |||
| 116 | static DEFINE_SPINLOCK(opti621_lock); | 111 | static DEFINE_SPINLOCK(opti621_lock); |
| 117 | 112 | ||
| 118 | static int cmpt_clk(int time, int bus_speed) | ||
| 119 | /* Returns (rounded up) time in clocks for time in ns, | ||
| 120 | * with bus_speed in MHz. | ||
| 121 | * Example: bus_speed = 40 MHz, time = 80 ns | ||
| 122 | * 1000/40 = 25 ns (clk value), | ||
| 123 | * 80/25 = 3.2, rounded up to 4 (I hope ;-)). | ||
| 124 | * Use idebus=xx to select right frequency. | ||
| 125 | */ | ||
| 126 | { | ||
| 127 | return ((time*bus_speed+999)/1000); | ||
| 128 | } | ||
| 129 | |||
| 130 | /* Write value to register reg, base of register | 113 | /* Write value to register reg, base of register |
| 131 | * is at reg_base (0x1f0 primary, 0x170 secondary, | 114 | * is at reg_base (0x1f0 primary, 0x170 secondary, |
| 132 | * if not changed by PCI configuration). | 115 | * if not changed by PCI configuration). |
| @@ -159,51 +142,22 @@ static u8 read_reg(int reg) | |||
| 159 | return ret; | 142 | return ret; |
| 160 | } | 143 | } |
| 161 | 144 | ||
| 162 | typedef struct pio_clocks_s { | ||
| 163 | int address_time; /* Address setup (clocks) */ | ||
| 164 | int data_time; /* Active/data pulse (clocks) */ | ||
| 165 | int recovery_time; /* Recovery time (clocks) */ | ||
| 166 | } pio_clocks_t; | ||
| 167 | |||
| 168 | static void compute_clocks(int pio, pio_clocks_t *clks, int bus_speed) | ||
| 169 | { | ||
| 170 | if (pio != PIO_NOT_EXIST) { | ||
| 171 | int adr_setup, data_pls; | ||
| 172 | |||
| 173 | adr_setup = ide_pio_timings[pio].setup_time; | ||
| 174 | data_pls = ide_pio_timings[pio].active_time; | ||
| 175 | clks->address_time = cmpt_clk(adr_setup, bus_speed); | ||
| 176 | clks->data_time = cmpt_clk(data_pls, bus_speed); | ||
| 177 | clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time | ||
| 178 | - adr_setup-data_pls, bus_speed); | ||
| 179 | if (clks->address_time < 1) | ||
| 180 | clks->address_time = 1; | ||
| 181 | if (clks->address_time > 4) | ||
| 182 | clks->address_time = 4; | ||
| 183 | if (clks->data_time < 1) | ||
| 184 | clks->data_time = 1; | ||
| 185 | if (clks->data_time > 16) | ||
| 186 | clks->data_time = 16; | ||
| 187 | if (clks->recovery_time < 2) | ||
| 188 | clks->recovery_time = 2; | ||
| 189 | if (clks->recovery_time > 17) | ||
| 190 | clks->recovery_time = 17; | ||
| 191 | } else { | ||
| 192 | clks->address_time = 1; | ||
| 193 | clks->data_time = 1; | ||
| 194 | clks->recovery_time = 2; | ||
| 195 | /* minimal values */ | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | 145 | static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) |
| 200 | { | 146 | { |
| 201 | ide_hwif_t *hwif = drive->hwif; | 147 | ide_hwif_t *hwif = drive->hwif; |
| 202 | ide_drive_t *pair = ide_get_paired_drive(drive); | 148 | ide_drive_t *pair = ide_get_paired_drive(drive); |
| 203 | unsigned long flags; | 149 | unsigned long flags; |
| 204 | pio_clocks_t first, second; | 150 | u8 tim, misc, addr_pio = pio, clk; |
| 205 | int ax, drdy; | 151 | |
| 206 | u8 cycle1, misc, clk, addr_pio = pio; | 152 | /* DRDY is default 2 (by OPTi Databook) */ |
| 153 | static const u8 addr_timings[2][4] = { | ||
| 154 | { 0x20, 0x10, 0x00, 0x00 }, /* 33 MHz */ | ||
| 155 | { 0x10, 0x10, 0x00, 0x00 }, /* 25 MHz */ | ||
| 156 | }; | ||
| 157 | static const u8 data_rec_timings[2][4] = { | ||
| 158 | { 0x5b, 0x45, 0x32, 0x21 }, /* 33 MHz */ | ||
| 159 | { 0x48, 0x34, 0x21, 0x10 } /* 25 MHz */ | ||
| 160 | }; | ||
| 207 | 161 | ||
| 208 | drive->drive_data = XFER_PIO_0 + pio; | 162 | drive->drive_data = XFER_PIO_0 + pio; |
| 209 | 163 | ||
| @@ -230,31 +184,15 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 230 | 184 | ||
| 231 | printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33); | 185 | printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33); |
| 232 | 186 | ||
| 233 | compute_clocks(pio, &first, clk ? 25 : 33); | 187 | tim = data_rec_timings[clk][pio]; |
| 234 | compute_clocks(addr_pio, &second, clk ? 25 : 33); | 188 | misc = addr_timings[clk][addr_pio]; |
| 235 | |||
| 236 | /* ax = max(a1,a2) */ | ||
| 237 | ax = (first.address_time < second.address_time) ? second.address_time : first.address_time; | ||
| 238 | |||
| 239 | drdy = 2; /* DRDY is default 2 (by OPTi Databook) */ | ||
| 240 | |||
| 241 | cycle1 = ((first.data_time-1)<<4) | (first.recovery_time-2); | ||
| 242 | |||
| 243 | misc = ((ax - 1) << 4) | ((drdy - 2) << 1); | ||
| 244 | |||
| 245 | #ifdef OPTI621_DEBUG | ||
| 246 | printk("%s: address: %d, data: %d, " | ||
| 247 | "recovery: %d, drdy: %d [clk]\n", | ||
| 248 | drive->name, ax, first.data_time, | ||
| 249 | first.recovery_time, drdy); | ||
| 250 | #endif | ||
| 251 | 189 | ||
| 252 | /* select Index-0/1 for Register-A/B */ | 190 | /* select Index-0/1 for Register-A/B */ |
| 253 | write_reg(drive->select.b.unit, MISC_REG); | 191 | write_reg(drive->select.b.unit, MISC_REG); |
| 254 | /* set read cycle timings */ | 192 | /* set read cycle timings */ |
| 255 | write_reg(cycle1, READ_REG); | 193 | write_reg(tim, READ_REG); |
| 256 | /* set write cycle timings */ | 194 | /* set write cycle timings */ |
| 257 | write_reg(cycle1, WRITE_REG); | 195 | write_reg(tim, WRITE_REG); |
| 258 | 196 | ||
| 259 | /* use Register-A for drive 0 */ | 197 | /* use Register-A for drive 0 */ |
| 260 | /* use Register-B for drive 1 */ | 198 | /* use Register-B for drive 1 */ |
