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
Kirill Smelkov
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