Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
70a83a8c
Commit
70a83a8c
authored
Jul 31, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://cifs.bkbits.net/linux-2.5cifs
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
62401684
f03a6bbb
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
198 additions
and
42 deletions
+198
-42
drivers/ide/pci/hpt366.c
drivers/ide/pci/hpt366.c
+197
-42
include/linux/pci_ids.h
include/linux/pci_ids.h
+1
-0
No files found.
drivers/ide/pci/hpt366.c
View file @
70a83a8c
/*
* linux/drivers/ide/pci/hpt366.c Version 0.3
4 Sept 17, 2002
* linux/drivers/ide/pci/hpt366.c Version 0.3
6 April 25, 2003
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
*
* Thanks to HighPoint Technologies for their assistance, and hardware.
* Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
...
...
@@ -39,6 +40,13 @@
* Reset the hpt366 on error, reset on dma
* Fix disabling Fast Interrupt hpt366.
* Mike Waychison <crlf@sun.com>
*
* Added support for 372N clocking and clock switching. The 372N needs
* different clocks on read/write. This requires overloading rw_disk and
* other deeply crazy things. Thanks to <http://www.hoerstreich.de> for
* keeping me sane.
* Alan Cox <alan@redhat.com>
*
*/
...
...
@@ -168,6 +176,9 @@ static u32 hpt_revision (struct pci_dev *dev)
class_rev
&=
0xff
;
switch
(
dev
->
device
)
{
/* Remap new 372N onto 372 */
case
PCI_DEVICE_ID_TTI_HPT372N
:
class_rev
=
PCI_DEVICE_ID_TTI_HPT372
;
break
;
case
PCI_DEVICE_ID_TTI_HPT374
:
class_rev
=
PCI_DEVICE_ID_TTI_HPT374
;
break
;
case
PCI_DEVICE_ID_TTI_HPT371
:
...
...
@@ -217,6 +228,11 @@ static u8 hpt3xx_ratemask (ide_drive_t *drive)
return
mode
;
}
/*
* Note for the future; the SATA hpt37x we must set
* either PIO or UDMA modes 0,4,5
*/
static
u8
hpt3xx_ratefilter
(
ide_drive_t
*
drive
,
u8
speed
)
{
struct
pci_dev
*
dev
=
HWIF
(
drive
)
->
pci_dev
;
...
...
@@ -672,6 +688,69 @@ static int hpt374_ide_dma_end (ide_drive_t *drive)
return
__ide_dma_end
(
drive
);
}
/**
* hpt372n_set_clock - perform clock switching dance
* @drive: Drive to switch
* @mode: Switching mode (0x21 for write, 0x23 otherwise)
*
* Switch the DPLL clock on the HPT372N devices. This is a
* right mess.
*/
static
void
hpt372n_set_clock
(
ide_drive_t
*
drive
,
int
mode
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
/* FIXME: should we check for DMA active and BUG() */
/* Tristate the bus */
outb
(
0x80
,
hwif
->
dma_base
+
0x73
);
outb
(
0x80
,
hwif
->
dma_base
+
0x77
);
/* Switch clock and reset channels */
outb
(
mode
,
hwif
->
dma_base
+
0x7B
);
outb
(
0xC0
,
hwif
->
dma_base
+
0x79
);
/* Reset state machines */
outb
(
0x37
,
hwif
->
dma_base
+
0x70
);
outb
(
0x37
,
hwif
->
dma_base
+
0x74
);
/* Complete reset */
outb
(
0x00
,
hwif
->
dma_base
+
0x79
);
/* Reconnect channels to bus */
outb
(
0x00
,
hwif
->
dma_base
+
0x73
);
outb
(
0x00
,
hwif
->
dma_base
+
0x77
);
}
/**
* hpt372n_rw_disk - wrapper for I/O
* @drive: drive for command
* @rq: block request structure
* @block: block number
*
* This is called when a disk I/O is issued to the 372N instead
* of the default functionality. We need it because of the clock
* switching
*
*/
static
ide_startstop_t
hpt372n_rw_disk
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
sector_t
block
)
{
int
wantclock
;
if
(
rq_data_dir
(
rq
)
==
READ
)
wantclock
=
0x21
;
else
wantclock
=
0x23
;
if
(
HWIF
(
drive
)
->
config_data
!=
wantclock
)
{
hpt372n_set_clock
(
drive
,
wantclock
);
HWIF
(
drive
)
->
config_data
=
wantclock
;
}
return
__ide_do_rw_disk
(
drive
,
rq
,
block
);
}
/*
* Since SUN Cobalt is attempting to do this operation, I should disclose
* this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date
...
...
@@ -793,13 +872,23 @@ static int __devinit init_hpt37x(struct pci_dev *dev)
u16
freq
;
u32
pll
;
u8
reg5bh
;
#if 1
u8
reg5ah
=
0
;
unsigned
long
dmabase
=
pci_resource_start
(
dev
,
4
);
u8
did
,
rid
;
int
is_372n
=
0
;
pci_read_config_byte
(
dev
,
0x5a
,
&
reg5ah
);
/* interrupt force enable */
pci_write_config_byte
(
dev
,
0x5a
,
(
reg5ah
&
~
0x10
));
#endif
if
(
dmabase
)
{
did
=
inb
(
dmabase
+
0x22
);
rid
=
inb
(
dmabase
+
0x28
);
if
((
did
==
4
&&
rid
==
6
)
||
(
did
==
5
&&
rid
>
1
))
is_372n
=
1
;
}
/*
* default to pci clock. make sure MA15/16 are set to output
...
...
@@ -810,47 +899,86 @@ static int __devinit init_hpt37x(struct pci_dev *dev)
/*
* set up the PLL. we need to adjust it so that it's stable.
* freq = Tpll * 192 / Tpci
*
* Todo. For non x86 should probably check the dword is
* set to 0xABCDExxx indicating the BIOS saved f_CNT
*/
pci_read_config_word
(
dev
,
0x78
,
&
freq
);
freq
&=
0x1FF
;
if
(
freq
<
0xa0
)
{
pll
=
F_LOW_PCI_33
;
if
(
hpt_minimum_revision
(
dev
,
8
))
pci_set_drvdata
(
dev
,
(
void
*
)
thirty_three_base_hpt374
);
else
if
(
hpt_minimum_revision
(
dev
,
5
))
pci_set_drvdata
(
dev
,
(
void
*
)
thirty_three_base_hpt372
);
else
if
(
hpt_minimum_revision
(
dev
,
4
))
pci_set_drvdata
(
dev
,
(
void
*
)
thirty_three_base_hpt370a
);
/*
* The 372N uses different PCI clock information and has
* some other complications
* On PCI33 timing we must clock switch
* On PCI66 timing we must NOT use the PCI clock
*
* Currently we always set up the PLL for the 372N
*/
pci_set_drvdata
(
dev
,
NULL
);
if
(
is_372n
)
{
printk
(
KERN_INFO
"hpt: HPT372N detected, using 372N timing.
\n
"
);
if
(
freq
<
0x55
)
pll
=
F_LOW_PCI_33
;
else
if
(
freq
<
0x70
)
pll
=
F_LOW_PCI_40
;
else
if
(
freq
<
0x7F
)
pll
=
F_LOW_PCI_50
;
else
pci_set_drvdata
(
dev
,
(
void
*
)
thirty_three_base_hpt370
);
printk
(
"HPT37X: using 33MHz PCI clock
\n
"
);
}
else
if
(
freq
<
0xb0
)
{
pll
=
F_LOW_PCI_40
;
}
else
if
(
freq
<
0xc8
)
{
pll
=
F_LOW_PCI_50
;
if
(
hpt_minimum_revision
(
dev
,
8
))
pci_set_drvdata
(
dev
,
NULL
);
else
if
(
hpt_minimum_revision
(
dev
,
5
))
pci_set_drvdata
(
dev
,
(
void
*
)
fifty_base_hpt372
);
else
if
(
hpt_minimum_revision
(
dev
,
4
))
pci_set_drvdata
(
dev
,
(
void
*
)
fifty_base_hpt370a
);
pll
=
F_LOW_PCI_66
;
printk
(
KERN_INFO
"FREQ: %d PLL: %d
\n
"
,
freq
,
pll
);
/* We always use the pll not the PCI clock on 372N */
}
else
{
if
(
freq
<
0x9C
)
pll
=
F_LOW_PCI_33
;
else
if
(
freq
<
0xb0
)
pll
=
F_LOW_PCI_40
;
else
if
(
freq
<
0xc8
)
pll
=
F_LOW_PCI_50
;
else
pci_set_drvdata
(
dev
,
(
void
*
)
fifty_base_hpt370a
);
printk
(
"HPT37X: using 50MHz PCI clock
\n
"
);
}
else
{
pll
=
F_LOW_PCI_66
;
if
(
hpt_minimum_revision
(
dev
,
8
))
{
printk
(
KERN_ERR
"HPT37x: 66MHz timings are not supported.
\n
"
);
pci_set_drvdata
(
dev
,
NULL
);
pll
=
F_LOW_PCI_66
;
if
(
pll
==
F_LOW_PCI_33
)
{
if
(
hpt_minimum_revision
(
dev
,
8
))
pci_set_drvdata
(
dev
,
(
void
*
)
thirty_three_base_hpt374
);
else
if
(
hpt_minimum_revision
(
dev
,
5
))
pci_set_drvdata
(
dev
,
(
void
*
)
thirty_three_base_hpt372
);
else
if
(
hpt_minimum_revision
(
dev
,
4
))
pci_set_drvdata
(
dev
,
(
void
*
)
thirty_three_base_hpt370a
);
else
pci_set_drvdata
(
dev
,
(
void
*
)
thirty_three_base_hpt370
);
printk
(
"HPT37X: using 33MHz PCI clock
\n
"
);
}
else
if
(
pll
==
F_LOW_PCI_40
)
{
/* Unsupported */
}
else
if
(
pll
==
F_LOW_PCI_50
)
{
if
(
hpt_minimum_revision
(
dev
,
8
))
pci_set_drvdata
(
dev
,
NULL
);
else
if
(
hpt_minimum_revision
(
dev
,
5
))
pci_set_drvdata
(
dev
,
(
void
*
)
fifty_base_hpt372
);
else
if
(
hpt_minimum_revision
(
dev
,
4
))
pci_set_drvdata
(
dev
,
(
void
*
)
fifty_base_hpt370a
);
else
pci_set_drvdata
(
dev
,
(
void
*
)
fifty_base_hpt370a
);
printk
(
"HPT37X: using 50MHz PCI clock
\n
"
);
}
else
{
if
(
hpt_minimum_revision
(
dev
,
8
))
{
printk
(
KERN_ERR
"HPT37x: 66MHz timings are not supported.
\n
"
);
}
else
if
(
hpt_minimum_revision
(
dev
,
5
))
pci_set_drvdata
(
dev
,
(
void
*
)
sixty_six_base_hpt372
);
else
if
(
hpt_minimum_revision
(
dev
,
4
))
pci_set_drvdata
(
dev
,
(
void
*
)
sixty_six_base_hpt370a
);
else
pci_set_drvdata
(
dev
,
(
void
*
)
sixty_six_base_hpt370
);
printk
(
"HPT37X: using 66MHz PCI clock
\n
"
);
}
else
if
(
hpt_minimum_revision
(
dev
,
5
))
pci_set_drvdata
(
dev
,
(
void
*
)
sixty_six_base_hpt372
);
else
if
(
hpt_minimum_revision
(
dev
,
4
))
pci_set_drvdata
(
dev
,
(
void
*
)
sixty_six_base_hpt370a
);
else
pci_set_drvdata
(
dev
,
(
void
*
)
sixty_six_base_hpt370
);
printk
(
"HPT37X: using 66MHz PCI clock
\n
"
);
}
/*
...
...
@@ -863,6 +991,11 @@ static int __devinit init_hpt37x(struct pci_dev *dev)
if
(
pci_get_drvdata
(
dev
))
goto
init_hpt37X_done
;
if
(
hpt_minimum_revision
(
dev
,
8
))
{
printk
(
KERN_ERR
"HPT374: Only 33MHz PCI timings are supported.
\n
"
);
return
-
EOPNOTSUPP
;
}
/*
* adjust PLL based upon PCI clock, enable it, and wait for
* stabilization.
...
...
@@ -1000,12 +1133,27 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
{
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
u8
ata66
=
0
,
regmask
=
(
hwif
->
channel
)
?
0x01
:
0x02
;
u8
did
,
rid
;
unsigned
long
dmabase
=
hwif
->
dma_base
;
int
is_372n
=
0
;
if
(
dmabase
)
{
did
=
inb
(
dmabase
+
0x22
);
rid
=
inb
(
dmabase
+
0x28
);
if
((
did
==
4
&&
rid
==
6
)
||
(
did
==
5
&&
rid
>
1
))
is_372n
=
1
;
}
hwif
->
tuneproc
=
&
hpt3xx_tune_drive
;
hwif
->
speedproc
=
&
hpt3xx_tune_chipset
;
hwif
->
quirkproc
=
&
hpt3xx_quirkproc
;
hwif
->
intrproc
=
&
hpt3xx_intrproc
;
hwif
->
maskproc
=
&
hpt3xx_maskproc
;
if
(
is_372n
)
hwif
->
rw_disk
=
&
hpt372n_rw_disk
;
/*
* The HPT37x uses the CBLID pins as outputs for MA15/MA16
...
...
@@ -1179,7 +1327,8 @@ static void __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d
u8
pin1
=
0
,
pin2
=
0
;
unsigned
int
class_rev
;
char
*
chipset_names
[]
=
{
"HPT366"
,
"HPT366"
,
"HPT368"
,
"HPT370"
,
"HPT370A"
,
"HPT372"
};
"HPT370"
,
"HPT370A"
,
"HPT372"
,
"HPT372N"
};
if
(
PCI_FUNC
(
dev
->
devfn
)
&
1
)
return
;
...
...
@@ -1187,9 +1336,14 @@ static void __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d
pci_read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class_rev
);
class_rev
&=
0xff
;
strcpy
(
d
->
name
,
chipset_names
[
class_rev
]);
if
(
dev
->
device
==
PCI_DEVICE_ID_TTI_HPT372N
)
class_rev
=
6
;
if
(
class_rev
<=
6
)
d
->
name
=
chipset_names
[
class_rev
];
switch
(
class_rev
)
{
case
6
:
case
5
:
case
4
:
case
3
:
ide_setup_pci_device
(
dev
,
d
);
...
...
@@ -1243,6 +1397,7 @@ static struct pci_device_id hpt366_pci_tbl[] = {
{
PCI_VENDOR_ID_TTI
,
PCI_DEVICE_ID_TTI_HPT302
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
2
},
{
PCI_VENDOR_ID_TTI
,
PCI_DEVICE_ID_TTI_HPT371
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
3
},
{
PCI_VENDOR_ID_TTI
,
PCI_DEVICE_ID_TTI_HPT374
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
4
},
{
PCI_VENDOR_ID_TTI
,
PCI_DEVICE_ID_TTI_HPT372N
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
5
},
{
0
,
},
};
MODULE_DEVICE_TABLE
(
pci
,
hpt366_pci_tbl
);
...
...
include/linux/pci_ids.h
View file @
70a83a8c
...
...
@@ -1184,6 +1184,7 @@
#define PCI_DEVICE_ID_TTI_HPT302 0x0006
#define PCI_DEVICE_ID_TTI_HPT371 0x0007
#define PCI_DEVICE_ID_TTI_HPT374 0x0008
#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 // apparently a 372N variant?
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_DEVICE_ID_VIA_8763_0 0x0198
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment