Support Marvell Hercules-I/II SATA Controllers.
This commit is contained in:
parent
fdc1dac9e9
commit
ce1343fcd9
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.1148 2009/07/25 16:22:59 mbalmer Exp $
|
||||
# $NetBSD: mi,v 1.1149 2009/07/27 12:34:12 kiyohara Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
|
@ -1216,6 +1216,7 @@
|
|||
./usr/share/man/cat4/mvme68k/pcctwo.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/mvme68k/wdsc.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/mvme68k/zsc.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/mvsata.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/nadb.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/nca.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/ncr.0 man-obsolete obsolete
|
||||
|
@ -3782,6 +3783,7 @@
|
|||
./usr/share/man/html4/mvme68k/pcctwo.html man-sys-htmlman html
|
||||
./usr/share/man/html4/mvme68k/wdsc.html man-sys-htmlman html
|
||||
./usr/share/man/html4/mvme68k/zsc.html man-sys-htmlman html
|
||||
./usr/share/man/html4/mvsata.html man-sys-htmlman html
|
||||
./usr/share/man/html4/nadb.html man-sys-htmlman html
|
||||
./usr/share/man/html4/nca.html man-sys-htmlman html
|
||||
./usr/share/man/html4/ne.html man-sys-htmlman html
|
||||
|
@ -6206,6 +6208,7 @@
|
|||
./usr/share/man/man4/mvme68k/pcctwo.4 man-sys-man .man
|
||||
./usr/share/man/man4/mvme68k/wdsc.4 man-sys-man .man
|
||||
./usr/share/man/man4/mvme68k/zsc.4 man-sys-man .man
|
||||
./usr/share/man/man4/mvsata.4 man-sys-man .man
|
||||
./usr/share/man/man4/nadb.4 man-sys-man .man
|
||||
./usr/share/man/man4/nca.4 man-sys-man .man
|
||||
./usr/share/man/man4/ncr.4 man-obsolete obsolete
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1260 $>
|
||||
# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1261 $>
|
||||
#
|
||||
#
|
||||
# [Note: This file does not mention every change made to the NetBSD source tree.
|
||||
|
@ -340,3 +340,5 @@ Changes from NetBSD 5.0 to NetBSD 6.0:
|
|||
[mbalmer 20090725]
|
||||
secmodel_44bsd(9), secmodel_securelevel(9): Add provisions to control
|
||||
acces to gpio(4) pins. [mbalmer 20090725]
|
||||
mvsata(4): Support Marvell Hercules-I/II SATA Controllers
|
||||
[kiyohara 20090615]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.492 2009/06/05 07:21:14 hubertf Exp $
|
||||
# $NetBSD: Makefile,v 1.493 2009/07/27 12:34:13 kiyohara Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/18/93
|
||||
|
||||
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 acpidalb.4 \
|
||||
|
@ -36,7 +36,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 acpidalb.4 \
|
|||
lc.4 ld.4 lii.4 lo.4 lxtphy.4 \
|
||||
mainbus.4 makphy.4 mbe.4 mca.4 mcclock.4 md.4 mfb.4 mfi.4 mhzc.4 \
|
||||
midi.4 mii.4 mk48txx.4 mlx.4 mly.4 mpt.4 mpu.4 mtd.4 mtio.4 \
|
||||
multicast.4 \
|
||||
multicast.4 mvsata.4 \
|
||||
nadb.4 ne.4 neo.4 netintro.4 nfe.4 nfsmb.4 njata.4 njs.4 \
|
||||
nsclpcsio.4 nsp.4 nsphy.4 nsphyter.4 ntwoc.4 null.4 nsmb.4 \
|
||||
oak.4 oosiop.4 opl.4 options.4 optiide.4 osiop.4 \
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
.\" $NetBSD: mvsata.4,v 1.1 2009/07/27 12:34:13 kiyohara Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009 KIYOHARA Takashi
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd July 19, 2009
|
||||
.Dt MVSATA 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mvsata
|
||||
.Nd Marvell Hercules-I and Hercules-II SATA controllers driver
|
||||
.Sh SYNOPSIS
|
||||
.Cd "mvsata* at pci? dev ? function ?"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver supports the Marvell Hercules-I and Hercules-II family of SATA
|
||||
controllers,
|
||||
interfacing the hardware with the
|
||||
.Xr ata 4
|
||||
and
|
||||
.Xr atapi 4
|
||||
subsystems.
|
||||
.Pp
|
||||
The following controllers are supported by the
|
||||
.Nm
|
||||
driver:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Marvell 88SX50xx Hercules-I
|
||||
.It Marvell 88SX60xx Hercules-II
|
||||
.It Adaptec RAID 1420SA
|
||||
.It Marvell 88SX70xx Hercules-II
|
||||
.It Adaptec RAID 1430SA
|
||||
.It Triones Technologies RocketRAID 2310 RAID card
|
||||
.El
|
||||
.Pp
|
||||
The 88SX60xx and later supports Native Command Queue. Also the 88SX70xx
|
||||
supports ATAPI.
|
||||
.Pp
|
||||
.Sh SEE ALSO
|
||||
.Xr ata 4 ,
|
||||
.Xr atapi 4 ,
|
||||
.Xr pci 4 ,
|
||||
.Xr wd 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
driver first appeared in
|
||||
.Nx 6.0 .
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An KIYOHARA Takashi Aq kiyohara@kk.iij4u.or.jp .
|
||||
.Sh BUGS
|
||||
.Bl -tag -width Ds -compact
|
||||
.It SATA Native Command Queuing is not yet supported .
|
||||
.It Device hot swapping is not yet supported .
|
||||
.It ATAPI is not yet tested .
|
||||
.It Marvell's Software RAID is not yet supported by the
|
||||
.Xr ataraid 4
|
||||
driver.
|
||||
.Xr raid 4
|
||||
can be used instead.
|
||||
.El
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: GENERIC,v 1.245 2009/07/19 06:28:08 kiyohara Exp $
|
||||
# $NetBSD: GENERIC,v 1.246 2009/07/27 12:34:13 kiyohara Exp $
|
||||
#
|
||||
# GENERIC machine description file
|
||||
#
|
||||
|
@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64"
|
|||
|
||||
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
|
||||
|
||||
#ident "GENERIC-$Revision: 1.245 $"
|
||||
#ident "GENERIC-$Revision: 1.246 $"
|
||||
|
||||
maxusers 64 # estimated number of users
|
||||
|
||||
|
@ -541,6 +541,7 @@ iteide* at pci? dev ? function ? # IT Express IDE controllers
|
|||
ixpide* at pci? dev ? function ? # ATI IXP IDE controllers
|
||||
jmide* at pci? dev ? function ? # JMicron PCI-e PATA/SATA controllers
|
||||
ahcisata* at jmide?
|
||||
mvsata* at pci? dev ? function ? # Marvell Hercules-I/II
|
||||
optiide* at pci? dev ? function ? # Opti IDE controllers
|
||||
piixide* at pci? dev ? function ? # Intel IDE controllers
|
||||
pdcide* at pci? dev ? function ? # Promise IDE controllers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: ALL,v 1.201 2009/07/25 19:04:41 cegger Exp $
|
||||
# $NetBSD: ALL,v 1.202 2009/07/27 12:34:13 kiyohara Exp $
|
||||
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
|
||||
#
|
||||
# ALL machine description file
|
||||
|
@ -17,7 +17,7 @@ include "arch/i386/conf/std.i386"
|
|||
|
||||
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
|
||||
|
||||
#ident "ALL-$Revision: 1.201 $"
|
||||
#ident "ALL-$Revision: 1.202 $"
|
||||
|
||||
maxusers 32 # estimated number of users
|
||||
|
||||
|
@ -811,6 +811,7 @@ iteide* at pci? dev ? function ? # IT Express IDE controllers
|
|||
ixpide* at pci? dev ? function ? # ATI IXP IDE controllers
|
||||
jmide* at pci? dev ? function ? # JMicron PCI-e PATA/SATA controllers
|
||||
ahcisata* at jmide?
|
||||
mvsata* at pci? dev ? function ? # Marvell Hercules-I/II
|
||||
optiide* at pci? dev ? function ? # Opti IDE controllers
|
||||
piixide* at pci? dev ? function ? # Intel IDE controllers
|
||||
pdcide* at pci? dev ? function ? # Promise IDE controllers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: GENERIC,v 1.937 2009/07/19 06:28:08 kiyohara Exp $
|
||||
# $NetBSD: GENERIC,v 1.938 2009/07/27 12:34:13 kiyohara Exp $
|
||||
#
|
||||
# GENERIC machine description file
|
||||
#
|
||||
|
@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386"
|
|||
|
||||
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
|
||||
|
||||
#ident "GENERIC-$Revision: 1.937 $"
|
||||
#ident "GENERIC-$Revision: 1.938 $"
|
||||
|
||||
maxusers 64 # estimated number of users
|
||||
|
||||
|
@ -798,6 +798,7 @@ iteide* at pci? dev ? function ? # IT Express IDE controllers
|
|||
ixpide* at pci? dev ? function ? # ATI IXP IDE controllers
|
||||
jmide* at pci? dev ? function ? # JMicron PCI-e PATA/SATA controllers
|
||||
ahcisata* at jmide?
|
||||
mvsata* at pci? dev ? function ? # Marvell Hercules-I/II
|
||||
optiide* at pci? dev ? function ? # Opti IDE controllers
|
||||
piixide* at pci? dev ? function ? # Intel IDE controllers
|
||||
pdcide* at pci? dev ? function ? # Promise IDE controllers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files,v 1.950 2009/07/18 16:31:42 reinoud Exp $
|
||||
# $NetBSD: files,v 1.951 2009/07/27 12:34:13 kiyohara Exp $
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
||||
version 20090313
|
||||
|
@ -940,6 +940,12 @@ define ahcisata_core
|
|||
file dev/ic/ahcisata_core.c ahcisata_core
|
||||
device ahcisata: ata, ata_dma, ata_udma, sata, sata_fis, ahcisata_core
|
||||
|
||||
# Mervell Serial-ATA Host Controller
|
||||
define mvsata
|
||||
file dev/ic/mvsata.c mvsata
|
||||
device mvsata: ata, ata_dma, ata_udma, wdc_common, sata, mvsata
|
||||
defflag opt_mvsata.h MVSATA_WITHOUTDMA
|
||||
|
||||
# DECchip 21x4x Ethernet controller family, and assorted clones.
|
||||
#
|
||||
device tlp: arp, ether, ifnet, mii, mii_bitbang
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: DEVNAMES,v 1.245 2009/02/19 00:55:48 jmcneill Exp $
|
||||
# $NetBSD: DEVNAMES,v 1.246 2009/07/27 12:34:13 kiyohara Exp $
|
||||
#
|
||||
# This file contains all used device names and defined attributes in
|
||||
# alphabetical order. New devices added to the system somewhere should first
|
||||
|
@ -882,6 +882,7 @@ mtd MI
|
|||
mtty MI
|
||||
mu vax
|
||||
mulaw MI Attribute
|
||||
mvsata MI
|
||||
nca MI
|
||||
ncr5380sbc MI Attribute
|
||||
ncr53c9x MI Attribute
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,326 @@
|
|||
/* $NetBSD: mvsatareg.h,v 1.1 2009/07/27 12:34:14 kiyohara Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 KIYOHARA Takashi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MVSATAREG_H_
|
||||
#define _MVSATAREG_H_
|
||||
|
||||
/*
|
||||
* SATAHC Arbiter Registers
|
||||
*/
|
||||
#define SATAHC_REGISTER_SIZE 0x10000
|
||||
#define SATAHC(hc) ((hc) * SATAHC_REGISTER_SIZE)
|
||||
|
||||
#define SATAHC_C 0x000 /* Configuration */
|
||||
#define SATAHC_C_TIMEOUT_MASK (0xff << 0)
|
||||
#define SATAHC_C_TIMEOUTEN (1 << 16) /* Timer Enable */
|
||||
#define SATAHC_C_COALDIS(p) (1 << ((p) + 24))/* Coalescing Disable*/
|
||||
#define SATAHC_RQOP 0x004 /* Request Queue Out-Pointer */
|
||||
#define SATAHC_RQIP 0x008 /* Response Queue In-Pointer */
|
||||
#define SATAHC_RQP_ERPQP(p, x) (((x) >> ((p) * 8)) & 0x7f)
|
||||
#define SATAHC_ICT 0x00c /* Interrupt Coalescing Threshold */
|
||||
#define SATAHC_ICT_SAICOALT_MASK 0x000000ff
|
||||
#define SATAHC_ITT 0x010 /* Interrupt Time Threshold */
|
||||
#define SATAHC_ITT_SAITMTH 0x00ffffff
|
||||
#define SATAHC_IC 0x014 /* Interrupt Cause */
|
||||
#define SATAHC_IC_DONE(p) (1 << (p)) /* SaCrpb/DMA Done */
|
||||
#define SATAHC_IC_SAINTCOAL (1 << 4) /* Intr Coalescing */
|
||||
#define SATAHC_IC_SADEVINTERRUPT(p) (1 << ((p) + 8))/* Device Intr */
|
||||
|
||||
/*
|
||||
* Physical Registers for Generation I
|
||||
*/
|
||||
#define SATAHC_I_R02(p) ((p) * 0x100 + 0x108)
|
||||
#define SATAHC_I_PHYCONTROL(p) ((p) * 0x100 + 0x10c)
|
||||
#define SATAHC_I_LTMODE(p) ((p) * 0x100 + 0x130)
|
||||
#define SATAHC_I_PHYMODE(p) ((p) * 0x100 + 0x174)
|
||||
|
||||
|
||||
/*
|
||||
* EDMA Registers
|
||||
*/
|
||||
#define EDMA_REGISTERS_OFFSET 0x2000
|
||||
#define EDMA_REGISTERS_SIZE 0x2000
|
||||
|
||||
#define EDMA_CFG 0x000 /* Configuration */
|
||||
#define EDMA_CFG_RESERVED (0x1f << 0) /* Queue len ? */
|
||||
#define EDMA_CFG_ESATANATVCMDQUE (1 << 5)
|
||||
#define EDMA_CFG_ERDBSZ (1 << 8)
|
||||
#define EDMA_CFG_EQUE (1 << 9)
|
||||
#define EDMA_CFG_ERDBSZEXT (1 << 11)
|
||||
#define EDMA_CFG_RESERVED2 (1 << 12)
|
||||
#define EDMA_CFG_EWRBUFFERLEN (1 << 13)
|
||||
#define EDMA_CFG_EDEVERR (1 << 14)
|
||||
#define EDMA_CFG_EEDMAFBS (1 << 16)
|
||||
#define EDMA_CFG_ECUTTHROUGHEN (1 << 17)
|
||||
#define EDMA_CFG_EEARLYCOMPLETIONEN (1 << 18)
|
||||
#define EDMA_CFG_EEDMAQUELEN (1 << 19)
|
||||
#define EDMA_CFG_EHOSTQUEUECACHEEN (1 << 22)
|
||||
#define EDMA_CFG_EMASKRXPM (1 << 23)
|
||||
#define EDMA_CFG_RESUMEDIS (1 << 24)
|
||||
#define EDMA_CFG_EDMAFBS (1 << 26)
|
||||
#define EDMA_T 0x004 /* Timer */
|
||||
#define EDMA_IEC 0x008 /* Interrupt Error Cause */
|
||||
#define EDMA_IEM 0x00c /* Interrupt Error Mask */
|
||||
#define EDMA_IE_EDEVERR (1 << 2) /* EDMA Device Error */
|
||||
#define EDMA_IE_EDEVDIS (1 << 3) /* EDMA Dev Disconn */
|
||||
#define EDMA_IE_EDEVCON (1 << 4) /* EDMA Dev Conn */
|
||||
#define EDMA_IE_SERRINT (1 << 5)
|
||||
#define EDMA_IE_ESELFDIS (1 << 7) /* EDMA Self Disable */
|
||||
#define EDMA_IE_ETRANSINT (1 << 8) /* Transport Layer */
|
||||
#define EDMA_IE_EIORDYERR (1 << 12) /* EDMA IORdy Error */
|
||||
# define EDMA_IE_LINKXERR_SATACRC (1 << 0) /* SATA CRC error */
|
||||
# define EDMA_IE_LINKXERR_INTERNALFIFO (1 << 1) /* internal FIFO err */
|
||||
# define EDMA_IE_LINKXERR_LINKLAYERRESET (1 << 2)
|
||||
/* Link Layer is reset by the reception of SYNC primitive from device */
|
||||
# define EDMA_IE_LINKXERR_OTHERERRORS (1 << 3)
|
||||
/*
|
||||
* Link state errors, coding errors, or running disparity errors occur
|
||||
* during FIS reception.
|
||||
*/
|
||||
# define EDMA_IE_LINKTXERR_FISTXABORTED (1 << 4) /* FIS Tx is aborted */
|
||||
#define EDMA_IE_LINKCTLRXERR(x) ((x) << 13) /* Link Ctrl Recv Err */
|
||||
#define EDMA_IE_LINKDATARXERR(x) ((x) << 17) /* Link Data Recv Err */
|
||||
#define EDMA_IE_LINKCTLTXERR(x) ((x) << 21) /* Link Ctrl Tx Error */
|
||||
#define EDMA_IE_LINKDATATXERR(x) ((x) << 26) /* Link Data Tx Error */
|
||||
#define EDMA_IE_TRANSPROTERR (1 << 31) /* Transport Proto E */
|
||||
#define EDMA_REQQBAH 0x010 /* Request Queue Base Address High */
|
||||
#define EDMA_REQQIP 0x014 /* Request Queue In-Pointer */
|
||||
#define EDMA_REQQOP 0x018 /* Request Queue Out-Pointer */
|
||||
#define EDMA_REQQP_ERQQP_SHIFT 5
|
||||
#define EDMA_REQQP_ERQQP_MASK 0x000003e0
|
||||
#define EDMA_REQQP_ERQQBAP_MASK 0x00000c00
|
||||
#define EDMA_REQQP_ERQQBA_MASK 0xfffff000
|
||||
#define EDMA_RESQBAH 0x01c /* Response Queue Base Address High */
|
||||
#define EDMA_RESQIP 0x020 /* Response Queue In-Pointer */
|
||||
#define EDMA_RESQOP 0x024 /* Response Queue Out-Pointer */
|
||||
#define EDMA_RESQP_ERPQP_SHIFT 3
|
||||
#define EDMA_RESQP_ERPQP_MASK 0x000000f8
|
||||
#define EDMA_RESQP_ERPQBAP_MASK 0x00000300
|
||||
#define EDMA_RESQP_ERPQBA_MASK 0xfffffc00
|
||||
#define EDMA_CMD 0x028 /* Command */
|
||||
#define EDMA_CMD_EENEDMA (1 << 0) /* Enable EDMA */
|
||||
#define EDMA_CMD_EDSEDMA (1 << 1) /* Disable EDMA */
|
||||
#define EDMA_CMD_EATARST (1 << 2) /* ATA Device Reset */
|
||||
#define EDMA_CMD_EEDMAFRZ (1 << 4) /* EDMA Freeze */
|
||||
#define EDMA_TC 0x02c /* Test Control */
|
||||
#define EDMA_S 0x030 /* Status */
|
||||
#define EDMA_S_EDEVQUETAG(s) ((s) & 0x0000001f)
|
||||
#define EDMA_S_EDEVDIR_WRITE (0 << 5)
|
||||
#define EDMA_S_EDEVDIR_READ (1 << 5)
|
||||
#define EDMA_S_ECACHEEMPTY (1 << 6)
|
||||
#define EDMA_S_EDMAIDLE (1 << 7)
|
||||
#define EDMA_S_ESTATE(s) (((s) & 0x0000ff00) >> 8)
|
||||
#define EDMA_S_EIOID(s) (((s) & 0x003f0000) >> 16)
|
||||
#define EDMA_IORT 0x034 /* IORdy Timeout */
|
||||
#define EDMA_CDT 0x040 /* Command Delay Threshold */
|
||||
#define EDMA_HC 0x060 /* Halt Condition */
|
||||
#define EDMA_CQDCQOS(x) (0x090 + ((x) << 2)
|
||||
/* NCQ Done/TCQ Outstanding Status */
|
||||
|
||||
/*
|
||||
* Shadow Register Block Registers
|
||||
*/
|
||||
#define SHADOW_REG_BLOCK_OFFSET 0x100
|
||||
#define SHADOW_REG_BLOCK_SIZE 0x100
|
||||
|
||||
#define SRB_PIOD 0x000 /* PIO Data */
|
||||
#define SRB_FE 0x004 /* Feature/Error */
|
||||
#define SRB_SC 0x008 /* Sector Count */
|
||||
#define SRB_LBAL 0x00c /* LBA Low */
|
||||
#define SRB_LBAM 0x010 /* LBA Mid */
|
||||
#define SRB_LBAH 0x014 /* LBA High */
|
||||
#define SRB_H 0x018 /* Head */
|
||||
#define SRB_CS 0x01c /* Command/Status */
|
||||
#define SRB_CAS 0x020 /* Control/Alternate Status */
|
||||
|
||||
/*
|
||||
* Basic DMA Registers
|
||||
* Does support for this registers only 88Sx6xxx?
|
||||
*/
|
||||
#define DMA_C 0x224 /* Basic DMA Command */
|
||||
#define DMA_C_START (1 << 0)
|
||||
#define DMA_C_READ (1 << 3)
|
||||
#define DMA_C_DREGIONVALID (1 << 8)
|
||||
#define DMA_C_DREGIONLAST (1 << 9)
|
||||
#define DMA_C_CONTFROMPREV (1 << 10)
|
||||
#define DMA_C_DRBC(n) (((n) & 0xffff) << 16)
|
||||
#define DMA_S 0x228 /* Basic DMA Status */
|
||||
#define DMA_DTLBA 0x22c /* Descriptor Table Low Base Address */
|
||||
#define DMA_DTLBA_MASK 0xfffffff0
|
||||
#define DMA_DTHBA 0x230 /* Descriptor Table High Base Address */
|
||||
#define DMA_DRLA 0x234 /* Data Region Low Address */
|
||||
#define DMA_DRHA 0x238 /* Data Region High Address */
|
||||
|
||||
/*
|
||||
* Serial-ATA Registers
|
||||
*/
|
||||
#define SATA_SS 0x300 /* SStatus */
|
||||
#define SATA_SE 0x304 /* SError */
|
||||
#define SATA_SEIM 0x340 /* SError Interrupt Mask */
|
||||
#define SATA_SC 0x308 /* SControl */
|
||||
#define SATA_LTM 0x30c /* LTMode */
|
||||
#define SATA_PHYM3 0x310 /* PHY Mode 3 */
|
||||
#define SATA_PHYM4 0x314 /* PHY Mode 4 */
|
||||
#define SATA_PHYM1 0x32c /* PHY Mode 1 */
|
||||
#define SATA_PHYM2 0x330 /* PHY Mode 2 */
|
||||
#define SATA_BISTC 0x334 /* BIST Control */
|
||||
#define SATA_BISTDW1 0x338 /* BIST DW1 */
|
||||
#define SATA_BISTDW2 0x33c /* BIST DW2 */
|
||||
#define SATA_SATAICFG 0x050 /* Serial-ATA Interface Configuration */
|
||||
#define SATA_SATAICFG_REFCLKCNF_20MHZ (0 < 0)
|
||||
#define SATA_SATAICFG_REFCLKCNF_25MHZ (1 < 0)
|
||||
#define SATA_SATAICFG_REFCLKCNF_30MHZ (2 < 0)
|
||||
#define SATA_SATAICFG_REFCLKCNF_40MHZ (3 < 0)
|
||||
#define SATA_SATAICFG_REFCLKCNF_MASK (3 < 0)
|
||||
#define SATA_SATAICFG_REFCLKDIV_1 (0 < 2)
|
||||
#define SATA_SATAICFG_REFCLKDIV_2 (1 < 2) /* Used 20 or 25MHz */
|
||||
#define SATA_SATAICFG_REFCLKDIV_4 (2 < 2) /* Used 40MHz */
|
||||
#define SATA_SATAICFG_REFCLKDIV_3 (3 < 2) /* Used 30MHz */
|
||||
#define SATA_SATAICFG_REFCLKDIV_MASK (3 < 2)
|
||||
#define SATA_SATAICFG_REFCLKFEEDDIV_50 (0 < 4) /* or 100, when Gen2En is 1 */
|
||||
#define SATA_SATAICFG_REFCLKFEEDDIV_60 (1 < 4) /* or 120. Used 25MHz */
|
||||
#define SATA_SATAICFG_REFCLKFEEDDIV_75 (2 < 4) /* or 150. Used 20MHz */
|
||||
#define SATA_SATAICFG_REFCLKFEEDDIV_90 (3 < 4) /* or 180 */
|
||||
#define SATA_SATAICFG_REFCLKFEEDDIV_MASK (3 < 4)
|
||||
#define SATA_SATAICFG_PHYSSCEN (1 < 6)
|
||||
#define SATA_SATAICFG_GEN2EN (1 < 7)
|
||||
#define SATA_SATAICFG_COMMEN (1 < 8)
|
||||
#define SATA_SATAICFG_PHYSHUTDOWN (1 < 9)
|
||||
#define SATA_SATAICFG_TARGETMODE (1 < 10) /* 1 = Initiator */
|
||||
#define SATA_SATAICFG_COMCHANNEL (1 < 11)
|
||||
#define SATA_SATAICFG_IGNOREBSY (1 < 24)
|
||||
#define SATA_SATAICFG_LINKRSTEN (1 < 25)
|
||||
#define SATA_SATAICFG_CMDRETXDS (1 < 26)
|
||||
#define SATA_SATAICTL 0x344 /* Serial-ATA Interface Control */
|
||||
#define SATA_SATAITC 0x348 /* Serial-ATA Interface Test Control */
|
||||
#define SATA_SATAIS 0x34c /* Serial-ATA Interface Status */
|
||||
#define SATA_VU 0x35c /* Vendor Unique */
|
||||
#define SATA_FISC 0x360 /* FIS Configuration */
|
||||
#define SATA_FISC_FISWAIT4RDYEN_B0 (1 << 0) /* Device to Host FIS */
|
||||
#define SATA_FISC_FISWAIT4RDYEN_B1 (1 << 1) /* SDB FIS rcv with <N>bit 0 */
|
||||
#define SATA_FISC_FISWAIT4RDYEN_B2 (1 << 2) /* DMA Activate FIS */
|
||||
#define SATA_FISC_FISWAIT4RDYEN_B3 (1 << 3) /* DMA Setup FIS */
|
||||
#define SATA_FISC_FISWAIT4RDYEN_B4 (1 << 4) /* Data FIS first DW */
|
||||
#define SATA_FISC_FISWAIT4RDYEN_B5 (1 << 5) /* Data FIS entire FIS */
|
||||
#define SATA_FISC_FISWAIT4HOSTRDYEN_B0 (1 << 8)
|
||||
/* Device to Host FIS with <ERR> or <DF> */
|
||||
#define SATA_FISC_FISWAIT4HOSTRDYEN_B1 (1 << 9) /* SDB FIS rcv with <N>bit */
|
||||
#define SATA_FISC_FISWAIT4HOSTRDYEN_B2 (1 << 10) /* SDB FIS rcv with <ERR> */
|
||||
#define SATA_FISC_FISWAIT4HOSTRDYEN_B3 (1 << 11) /* BIST Acivate FIS */
|
||||
#define SATA_FISC_FISWAIT4HOSTRDYEN_B4 (1 << 12) /* PIO Setup FIS */
|
||||
#define SATA_FISC_FISWAIT4HOSTRDYEN_B5 (1 << 13) /* Data FIS with Link error */
|
||||
#define SATA_FISC_FISWAIT4HOSTRDYEN_B6 (1 << 14) /* Unrecognized FIS type */
|
||||
#define SATA_FISC_FISWAIT4HOSTRDYEN_B7 (1 << 15) /* Any FIS */
|
||||
#define SATA_FISC_FISDMAACTIVATESYNCRESP (1 << 16)
|
||||
#define SATA_FISC_FISUNRECTYPECONT (1 << 17)
|
||||
#define SATA_FISIC 0x364 /* FIS Interrupt Cause */
|
||||
#define SATA_FISIM 0x368 /* FIS Interrupt Mask */
|
||||
#define SATA_FISDW0 0x370 /* FIS DW0 */
|
||||
#define SATA_FISDW1 0x374 /* FIS DW1 */
|
||||
#define SATA_FISDW2 0x378 /* FIS DW2 */
|
||||
#define SATA_FISDW3 0x37c /* FIS DW3 */
|
||||
#define SATA_FISDW4 0x380 /* FIS DW4 */
|
||||
#define SATA_FISDW5 0x384 /* FIS DW5 */
|
||||
#define SATA_FISDW6 0x388 /* FIS DW6 */
|
||||
|
||||
|
||||
/* EDMA Command Request Block (CRQB) Data */
|
||||
struct crqb {
|
||||
uint32_t cprdbl; /* cPRD Desriptor Table Base Low Address */
|
||||
uint32_t cprdbh; /* cPRD Desriptor Table Base High Address */
|
||||
uint16_t ctrlflg; /* Control Flags */
|
||||
uint16_t atacommand[11];
|
||||
} __packed;
|
||||
|
||||
struct crqb_gen2e {
|
||||
uint32_t cprdbl; /* cPRD Desriptor Table Base Low Address */
|
||||
uint32_t cprdbh; /* cPRD Desriptor Table Base High Address */
|
||||
uint32_t ctrlflg; /* Control Flags */
|
||||
uint32_t drbc; /* Data Region Byte Count */
|
||||
uint32_t atacommand[4];
|
||||
} __packed;
|
||||
|
||||
|
||||
#define CRQB_CRQBL_EPRD_MASK 0xfffffff0
|
||||
#define CRQB_CRQBL_SDR_MASK 0xfffffffe /* Single data region mask */
|
||||
|
||||
/* Control Flags */
|
||||
#define CRQB_CDIR_WRITE (0 << 0)
|
||||
#define CRQB_CDIR_READ (1 << 0)
|
||||
#define CRQB_CDEVICEQUETAG(x) (((x) & 0x1f) << 1) /* CRQB Dev Queue Tag */
|
||||
#define CRQB_CHOSTQUETAG(x) (((x) & 0x7f) << 1) /* CRQB Host Q Tag */
|
||||
#define CRQB_CPMPORT(x) (((x) & 0xf) << 12) /* PM Port Transmit */
|
||||
#define CRQB_CPRDMODE_EPRD (0 << 16) /* PRD table */
|
||||
#define CRQB_CPRDMODE_SDR (1 << 16) /* Single data region */
|
||||
#define CRQB_CHOSTQUETAG_GEN2(x) (((x) & 0x7f) << 17) /* CRQB Host Q Tag G2 */
|
||||
|
||||
/* Data Region Byte Count */
|
||||
#define CRQB_CDRBC(x) (((x) & 0xfffe) << 0)
|
||||
|
||||
#define CRQB_ATACOMMAND(reg, val) \
|
||||
((reg << 8) | (val & 0xff))
|
||||
#define CRQB_ATACOMMAND_LAST (1 << 15)
|
||||
#define CRQB_ATACOMMAND_REG(reg) (((reg) >> 2) + 0x10)
|
||||
#define CRQB_ATACOMMAND_FEATURES CRQB_ATACOMMAND_REG(SRB_FE)
|
||||
#define CRQB_ATACOMMAND_SECTORCOUNT CRQB_ATACOMMAND_REG(SRB_SC)
|
||||
#define CRQB_ATACOMMAND_LBALOW CRQB_ATACOMMAND_REG(SRB_LBAL)
|
||||
#define CRQB_ATACOMMAND_LBAMID CRQB_ATACOMMAND_REG(SRB_LBAM)
|
||||
#define CRQB_ATACOMMAND_LBAHIGH CRQB_ATACOMMAND_REG(SRB_LBAH)
|
||||
#define CRQB_ATACOMMAND_DEVICE CRQB_ATACOMMAND_REG(SRB_H)
|
||||
#define CRQB_ATACOMMAND_COMMAND CRQB_ATACOMMAND_REG(SRB_CS)
|
||||
|
||||
|
||||
/* EDMA Phisical Region Descriptors (ePRD) Table Data Structure */
|
||||
struct eprd {
|
||||
uint32_t prdbal; /* address bits[31:1] */
|
||||
uint16_t bytecount; /* Byte Count */
|
||||
uint16_t eot; /* End Of Table */
|
||||
uint32_t prdbah; /* address bits[63:32] */
|
||||
uint32_t resv;
|
||||
} __packed;
|
||||
|
||||
#define EPRD_PRDBAL_MASK 0xfffffffe /* phy memory region mask */
|
||||
|
||||
#define EPRD_BYTECOUNT(x) (((x) & 0xffff) << 0)
|
||||
#define EPRD_EOT (1 << 15) /* End Of Table */
|
||||
|
||||
|
||||
/* EDMA Command Response Block (CRPB) Data */
|
||||
struct crpb {
|
||||
uint16_t id; /* CRPB ID */
|
||||
uint16_t rspflg; /* CPRB Response Flags */
|
||||
uint32_t ts; /* CPRB Time Stamp */
|
||||
} __packed;
|
||||
|
||||
/* ID */
|
||||
#define CRPB_CHOSTQUETAG(x) (((x) >> 0) & 0x7f) /* CRPB Host Q Tag */
|
||||
|
||||
/* Response Flags */
|
||||
#define CRPB_CEDMASTS(x) (((x) >> 0) & 0x7f) /* CRPB EDMA Status */
|
||||
#define CRPB_CDEVSTS(x) (((x) >> 8) & 0xff) /* CRPB Device Status */
|
||||
|
||||
#endif /* _MVSATAREG_H_ */
|
|
@ -0,0 +1,137 @@
|
|||
/* $NetBSD: mvsatavar.h,v 1.1 2009/07/27 12:34:14 kiyohara Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 KIYOHARA Takashi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MVSATAVAR_H_
|
||||
#define _MVSATAVAR_H_
|
||||
|
||||
#define MVSATA_EDMAQ_LEN 32 /* keep compatibility to gen1 */
|
||||
#define MVSATA_EDMAQ_INC(i) ((i) = ((i) + 1) % MVSATA_EDMAQ_LEN)
|
||||
#define MVSATA_HC_MAX 2
|
||||
#define MVSATA_PORT_MAX 4
|
||||
#define MVSATA_CHANNEL_MAX (MVSATA_HC_MAX * MVSATA_PORT_MAX)
|
||||
|
||||
|
||||
struct mvsata_port;
|
||||
|
||||
union mvsata_crqb {
|
||||
struct crqb crqb;
|
||||
struct crqb_gen2e crqb_gen2e;
|
||||
};
|
||||
|
||||
struct _fix_phy_param {
|
||||
uint32_t pre_amps; /* Pre/SignalAmps */
|
||||
|
||||
void (*_fix_phy)(struct mvsata_port *);
|
||||
};
|
||||
|
||||
struct mvsata_port {
|
||||
struct ata_channel port_ata_channel;
|
||||
|
||||
int port;
|
||||
struct mvsata_hc *port_hc;
|
||||
|
||||
enum {
|
||||
nodma,
|
||||
dma,
|
||||
queued,
|
||||
ncq,
|
||||
} port_edmamode;
|
||||
|
||||
int port_quetagidx; /* Host Queue Tag valiable */
|
||||
|
||||
int port_prev_erqqop; /* previous Req Queue Out-Pointer */
|
||||
bus_dma_tag_t port_dmat;
|
||||
union mvsata_crqb *port_crqb; /* EDMA Command Request Block */
|
||||
bus_dmamap_t port_crqb_dmamap;
|
||||
struct crpb *port_crpb; /* EDMA Command Response Block */
|
||||
bus_dmamap_t port_crpb_dmamap;
|
||||
struct eprd *port_eprd; /* EDMA Phy Region Description Table */
|
||||
bus_dmamap_t port_eprd_dmamap;
|
||||
struct {
|
||||
struct ata_xfer *xfer; /* queued xfer */
|
||||
bus_dmamap_t data_dmamap; /* DMA data buffer */
|
||||
bus_size_t eprd_offset; /* offset of ePRD buffer */
|
||||
struct eprd *eprd; /* ePRD buffer */
|
||||
} port_reqtbl[MVSATA_EDMAQ_LEN];
|
||||
|
||||
bus_space_tag_t port_iot;
|
||||
bus_space_handle_t port_ioh;
|
||||
bus_space_handle_t port_sata_scontrol; /* SATA Interface control reg */
|
||||
bus_space_handle_t port_sata_serror; /* SATA Interface error reg */
|
||||
bus_space_handle_t port_sata_sstatus; /* SATA Interface status reg */
|
||||
struct ata_queue port_ata_queue;
|
||||
|
||||
struct _fix_phy_param _fix_phy_param;
|
||||
};
|
||||
|
||||
struct mvsata_hc {
|
||||
int hc;
|
||||
struct mvsata_softc *hc_sc;
|
||||
|
||||
bus_space_tag_t hc_iot; /* Tag for SATAHC Arbiter */
|
||||
bus_space_handle_t hc_ioh; /* Handle for SATAHC Arbiter */
|
||||
|
||||
struct mvsata_port *hc_ports[MVSATA_CHANNEL_MAX];
|
||||
};
|
||||
|
||||
struct mvsata_softc {
|
||||
struct wdc_softc sc_wdcdev; /* common wdc definitions */
|
||||
|
||||
int sc_model;
|
||||
int sc_rev;
|
||||
enum {
|
||||
gen_unknown = 0,
|
||||
gen1,
|
||||
gen2,
|
||||
gen2e
|
||||
} sc_gen; /* Generation for LSI */
|
||||
int sc_hc; /* number of host controller */
|
||||
int sc_port; /* number of port/host */
|
||||
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
bus_dma_tag_t sc_dmat;
|
||||
|
||||
struct wdc_regs *sc_wdc_regs;
|
||||
struct ata_channel *sc_ata_channels[MVSATA_CHANNEL_MAX];
|
||||
struct mvsata_hc sc_hcs[MVSATA_HC_MAX];
|
||||
|
||||
int sc_flags;
|
||||
#define MVSATA_FLAGS_PCIE (1 << 0)
|
||||
|
||||
void (*sc_edma_setup_crqb)(struct mvsata_port *, int, int,
|
||||
struct ata_bio *);
|
||||
void (*sc_enable_intr)(struct mvsata_port *, int);
|
||||
};
|
||||
|
||||
int mvsata_attach(struct mvsata_softc *,
|
||||
int (*mvsata_sreset)(struct mvsata_softc *),
|
||||
int (*mvsata_misc_reset)(struct mvsata_softc *), int);
|
||||
int mvsata_intr(struct mvsata_hc *);
|
||||
int mvsata_error(struct mvsata_port *);
|
||||
|
||||
#endif /* _MVSATAVAR_H_ */
|
|
@ -0,0 +1,512 @@
|
|||
/* $NetBSD: mvsata_pci.c,v 1.1 2009/07/27 12:34:14 kiyohara Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 KIYOHARA Takashi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mvsata_pci.c,v 1.1 2009/07/27 12:34:14 kiyohara Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/pmf.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcidevs.h>
|
||||
#include <dev/pci/pciidereg.h>
|
||||
#include <dev/pci/pciidevar.h>
|
||||
|
||||
#include <dev/ic/mvsatareg.h>
|
||||
#include <dev/ic/mvsatavar.h>
|
||||
|
||||
#define MVSATA_PCI_HCARBITER_SPACE_OFFSET 0x20000
|
||||
|
||||
#define MVSATA_PCI_COMMAND 0x00c00
|
||||
#define MVSATA_PCI_COMMAND_MWRITECOMBINE (1 << 4)
|
||||
#define MVSATA_PCI_COMMAND_MREADCOMBINE (1 << 5)
|
||||
#define MVSATA_PCI_SERRMASK 0x00c28
|
||||
#define MVSATA_PCI_MSITRIGGER 0x00c38
|
||||
#define MVSATA_PCI_MODE 0x00d00
|
||||
#define MVSATA_PCI_DISCTIMER 0x00d04
|
||||
#define MVSATA_PCI_EROMBAR 0x00d2c
|
||||
#define MVSATA_PCI_MAINCS 0x00d30
|
||||
#define MVSATA_PCI_MAINCS_SPM (1 << 2) /* stop pci master */
|
||||
#define MVSATA_PCI_MAINCS_PME (1 << 3) /* pci master empty */
|
||||
#define MVSATA_PCI_MAINCS_GSR (1 << 4) /* glab soft reset */
|
||||
#define MVSATA_PCI_E_IRQCAUSE 0x01900
|
||||
#define MVSATA_PCI_E_IRQMASK 0x01910
|
||||
#define MVSATA_PCI_XBARTIMEOUT 0x01d04
|
||||
#define MVSATA_PCI_ERRLOWADDR 0x01d40
|
||||
#define MVSATA_PCI_ERRHIGHADDR 0x01d44
|
||||
#define MVSATA_PCI_ERRATTRIBUTE 0x01d48
|
||||
#define MVSATA_PCI_ERRCOMMAND 0x01d50
|
||||
#define MVSATA_PCI_IRQCAUSE 0x01d58
|
||||
#define MVSATA_PCI_IRQMASK 0x01d5c
|
||||
#define MVSATA_PCI_MAINIRQCAUSE 0x01d60
|
||||
#define MVSATA_PCI_MAINIRQMASK 0x01d64
|
||||
#define MVSATA_PCI_MAINIRQ_SATAERR(hc, port) \
|
||||
(1 << (((port) << 1) + (hc) * 9))
|
||||
#define MVSATA_PCI_MAINIRQ_SATADONE(hc, port) \
|
||||
(1 << (((port) << 1) + (hc) * 9 + 1))
|
||||
#define MVSATA_PCI_MAINIRQ_SATACOALDONE(hc) (1 << ((hc) * 9 + 8))
|
||||
#define MVSATA_PCI_MAINIRQ_PCI (1 << 18)
|
||||
#define MVSATA_PCI_FLASHCTL 0x1046c
|
||||
#define MVSATA_PCI_GPIOPORTCTL 0x104f0
|
||||
#define MVSATA_PCI_RESETCFG 0x180d8
|
||||
|
||||
#define MVSATA_PCI_DEV(psc) (psc->psc_sc.sc_wdcdev.sc_atac.atac_dev)
|
||||
|
||||
|
||||
struct mvsata_pci_softc {
|
||||
struct mvsata_softc psc_sc;
|
||||
|
||||
pci_chipset_tag_t psc_pc;
|
||||
pcitag_t psc_tag;
|
||||
|
||||
bus_space_tag_t psc_iot;
|
||||
bus_space_handle_t psc_ioh;
|
||||
|
||||
void *psc_ih;
|
||||
};
|
||||
|
||||
|
||||
static int mvsata_pci_match(device_t, struct cfdata *, void *);
|
||||
static void mvsata_pci_attach(device_t, device_t, void *);
|
||||
static int mvsata_pci_detach(device_t, int);
|
||||
|
||||
static int mvsata_pci_intr(void *);
|
||||
static bool mvsata_pci_resume(device_t PMF_FN_ARGS);
|
||||
|
||||
static int mvsata_pci_sreset(struct mvsata_softc *);
|
||||
static int mvsata_pci_misc_reset(struct mvsata_softc *);
|
||||
static void mvsata_pci_enable_intr(struct mvsata_port *, int);
|
||||
|
||||
|
||||
CFATTACH_DECL_NEW(mvsata_pci, sizeof(struct mvsata_pci_softc),
|
||||
mvsata_pci_match, mvsata_pci_attach, mvsata_pci_detach, NULL);
|
||||
|
||||
|
||||
/*
|
||||
* mvsata_pci_match()
|
||||
* This function returns 2, because mvsata is high priority more than pciide.
|
||||
*/
|
||||
static int
|
||||
mvsata_pci_match(device_t parent, struct cfdata *match, void *aux)
|
||||
{
|
||||
struct pci_attach_args *pa = aux;
|
||||
|
||||
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_MARVELL)
|
||||
switch (PCI_PRODUCT(pa->pa_id)) {
|
||||
case PCI_PRODUCT_MARVELL_88SX5040:
|
||||
case PCI_PRODUCT_MARVELL_88SX5041:
|
||||
case PCI_PRODUCT_MARVELL_88SX5080:
|
||||
case PCI_PRODUCT_MARVELL_88SX5081:
|
||||
case PCI_PRODUCT_MARVELL_88SX6040:
|
||||
case PCI_PRODUCT_MARVELL_88SX6041:
|
||||
case PCI_PRODUCT_MARVELL_88SX6042:
|
||||
case PCI_PRODUCT_MARVELL_88SX6080:
|
||||
case PCI_PRODUCT_MARVELL_88SX6081:
|
||||
case PCI_PRODUCT_MARVELL_88SX7042:
|
||||
return 2;
|
||||
}
|
||||
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ADP2)
|
||||
switch (PCI_PRODUCT(pa->pa_id)) {
|
||||
case PCI_PRODUCT_ADP2_1420SA:
|
||||
case PCI_PRODUCT_ADP2_1430SA:
|
||||
return 2;
|
||||
}
|
||||
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_TRIONES &&
|
||||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_TRIONES_ROCKETRAID_2310)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mvsata_pci_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct pci_attach_args *pa = aux;
|
||||
struct mvsata_pci_softc *psc = device_private(self);
|
||||
struct mvsata_softc *sc = &psc->psc_sc;
|
||||
pci_intr_handle_t intrhandle;
|
||||
pcireg_t csr;
|
||||
bus_size_t size;
|
||||
uint32_t reg, mask;
|
||||
int read_pre_amps, hc, port, rv;
|
||||
char devinfo[256];
|
||||
const char *intrstr;
|
||||
|
||||
sc->sc_wdcdev.sc_atac.atac_dev = self;
|
||||
sc->sc_model = PCI_PRODUCT(pa->pa_id);
|
||||
sc->sc_rev = PCI_REVISION(pa->pa_class);
|
||||
sc->sc_dmat = pa->pa_dmat;
|
||||
sc->sc_enable_intr = mvsata_pci_enable_intr;
|
||||
|
||||
pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
|
||||
aprint_naive(": Marvell Serial-ATA Host Controller\n");
|
||||
aprint_normal(": %s\n", devinfo);
|
||||
|
||||
/* Map I/O register */
|
||||
if (pci_mapreg_map(pa, PCI_MAPREG_START,
|
||||
PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
|
||||
&psc->psc_iot, &psc->psc_ioh, NULL, &size) != 0) {
|
||||
aprint_error_dev(self, "can't map registers\n");
|
||||
return;
|
||||
}
|
||||
psc->psc_pc = pa->pa_pc;
|
||||
psc->psc_tag = pa->pa_tag;
|
||||
|
||||
if (bus_space_subregion(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_HCARBITER_SPACE_OFFSET,
|
||||
size - MVSATA_PCI_HCARBITER_SPACE_OFFSET, &sc->sc_ioh)) {
|
||||
aprint_error_dev(self, "can't subregion registers\n");
|
||||
return;
|
||||
}
|
||||
sc->sc_iot = psc->psc_iot;
|
||||
|
||||
/* Enable device */
|
||||
csr = pci_conf_read(psc->psc_pc, psc->psc_tag, PCI_COMMAND_STATUS_REG);
|
||||
csr |= PCI_COMMAND_MASTER_ENABLE;
|
||||
pci_conf_write(psc->psc_pc, psc->psc_tag, PCI_COMMAND_STATUS_REG, csr);
|
||||
|
||||
if (pci_intr_map(pa, &intrhandle) != 0) {
|
||||
aprint_error_dev(self, "couldn't map interrupt\n");
|
||||
return;
|
||||
}
|
||||
intrstr = pci_intr_string(psc->psc_pc, intrhandle);
|
||||
psc->psc_ih = pci_intr_establish(psc->psc_pc, intrhandle, IPL_BIO,
|
||||
mvsata_pci_intr, sc);
|
||||
if (psc->psc_ih == NULL) {
|
||||
aprint_error_dev(self, "couldn't establish interrupt\n");
|
||||
return;
|
||||
}
|
||||
aprint_normal_dev(self, "interrupting at %s\n",
|
||||
intrstr ? intrstr : "unknown interrupt");
|
||||
|
||||
/*
|
||||
* Check if TWSI serial ROM initialization was triggered.
|
||||
* If so, then PRE/AMP configuration probably are set after
|
||||
* reset by serial ROM. If not then override the PRE/AMP
|
||||
* values.
|
||||
*/
|
||||
reg = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_RESETCFG);
|
||||
read_pre_amps = (reg & 0x00000001) ? 1 : 0;
|
||||
|
||||
rv = mvsata_attach(sc, mvsata_pci_sreset, mvsata_pci_misc_reset,
|
||||
read_pre_amps);
|
||||
if (rv != 0) {
|
||||
pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
|
||||
return;
|
||||
}
|
||||
|
||||
mask = MVSATA_PCI_MAINIRQ_PCI;
|
||||
for (hc = 0; hc < sc->sc_hc; hc++)
|
||||
for (port = 0; port < sc->sc_port; port++)
|
||||
mask |=
|
||||
MVSATA_PCI_MAINIRQ_SATAERR(hc, port) |
|
||||
MVSATA_PCI_MAINIRQ_SATADONE(hc, port);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINIRQMASK,
|
||||
mask);
|
||||
|
||||
if (!pmf_device_register(self, NULL, mvsata_pci_resume))
|
||||
aprint_error_dev(self, "couldn't establish power handler\n");
|
||||
}
|
||||
|
||||
static int
|
||||
mvsata_pci_detach(device_t self, int flags)
|
||||
{
|
||||
struct mvsata_pci_softc *psc = device_private(self);
|
||||
|
||||
/* XXXX: needs reset ? */
|
||||
|
||||
pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
|
||||
pmf_device_deregister(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mvsata_pci_intr(void *arg)
|
||||
{
|
||||
struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)arg;
|
||||
struct mvsata_softc *sc = &psc->psc_sc;
|
||||
uint32_t cause;
|
||||
int hc, port, handled = 0;
|
||||
|
||||
cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MAINIRQCAUSE);
|
||||
for (hc = 0; hc < sc->sc_hc; hc++)
|
||||
for (port = 0; port < sc->sc_port; port++)
|
||||
if (cause & MVSATA_PCI_MAINIRQ_SATAERR(hc, port)) {
|
||||
struct mvsata_port *mvport;
|
||||
|
||||
mvport = sc->sc_hcs[hc].hc_ports[port];
|
||||
handled |= mvsata_error(mvport);
|
||||
}
|
||||
for (hc = 0; hc < sc->sc_hc; hc++)
|
||||
if (cause &
|
||||
(MVSATA_PCI_MAINIRQ_SATADONE(hc, 0) |
|
||||
MVSATA_PCI_MAINIRQ_SATADONE(hc, 1) |
|
||||
MVSATA_PCI_MAINIRQ_SATADONE(hc, 2) |
|
||||
MVSATA_PCI_MAINIRQ_SATADONE(hc, 3)))
|
||||
handled |= mvsata_intr(&sc->sc_hcs[hc]);
|
||||
|
||||
if (cause & MVSATA_PCI_MAINIRQ_PCI) {
|
||||
uint32_t pe_cause;
|
||||
|
||||
if (sc->sc_flags & MVSATA_FLAGS_PCIE) {
|
||||
pe_cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_E_IRQCAUSE);
|
||||
aprint_error_dev(MVSATA_PCI_DEV(psc),
|
||||
"PCIe error: 0x%x\n", pe_cause);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_E_IRQCAUSE, ~pe_cause);
|
||||
} else {
|
||||
pe_cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_IRQCAUSE);
|
||||
aprint_error_dev(MVSATA_PCI_DEV(psc),
|
||||
"PCI error: 0x%x\n", pe_cause);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_IRQCAUSE, ~pe_cause);
|
||||
}
|
||||
|
||||
handled = 1; /* XXXXX */
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static bool
|
||||
mvsata_pci_resume(device_t dev PMF_FN_ARGS)
|
||||
{
|
||||
|
||||
/* not yet... */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mvsata_pci_sreset(struct mvsata_softc *sc)
|
||||
{
|
||||
struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)sc;
|
||||
uint32_t val;
|
||||
int i;
|
||||
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS);
|
||||
val |= MVSATA_PCI_MAINCS_SPM;
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS, val);
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
delay(1);
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MAINCS);
|
||||
if (val & MVSATA_PCI_MAINCS_PME)
|
||||
break;
|
||||
}
|
||||
if (!(val & MVSATA_PCI_MAINCS_PME)) {
|
||||
aprint_error_dev(MVSATA_PCI_DEV(psc),
|
||||
"PCI master won't flush\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* reset */
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS,
|
||||
val | MVSATA_PCI_MAINCS_GSR);
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS);
|
||||
delay(5);
|
||||
if (!(val & MVSATA_PCI_MAINCS_GSR)) {
|
||||
aprint_error_dev(MVSATA_PCI_DEV(psc),
|
||||
"can't set global reset\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* clear reset and *reenable the PCI master* (not mentioned in spec) */
|
||||
val &= ~(MVSATA_PCI_MAINCS_GSR | MVSATA_PCI_MAINCS_SPM);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS, val);
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS);
|
||||
delay(5);
|
||||
if (val & MVSATA_PCI_MAINCS_GSR) {
|
||||
aprint_error_dev(MVSATA_PCI_DEV(psc),
|
||||
"can't set global reset\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mvsata_pci_misc_reset(struct mvsata_softc *sc)
|
||||
{
|
||||
struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)sc;
|
||||
#define MVSATA_PCI_COMMAND_DEFAULT 0x0107e371
|
||||
#define MVSATA_PCI_COMMAND_PCI_CONVENTIONAL_ONLY 0x800003e0
|
||||
uint32_t val, pci_command = MVSATA_PCI_COMMAND_DEFAULT;
|
||||
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_FLASHCTL,
|
||||
0x0fcfffff);
|
||||
|
||||
if (sc->sc_gen == gen2 || sc->sc_gen == gen2e) {
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_GPIOPORTCTL);
|
||||
val &= 0x3;
|
||||
#if 0
|
||||
val |= 0x00000060;
|
||||
#else /* XXXX */
|
||||
val |= 0x00000070;
|
||||
#endif
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_GPIOPORTCTL, val);
|
||||
}
|
||||
|
||||
if (sc->sc_gen == gen1) {
|
||||
/* Expansion ROM BAR Enable */
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_EROMBAR);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_EROMBAR, val | 0x00000001);
|
||||
}
|
||||
|
||||
if (sc->sc_flags & MVSATA_FLAGS_PCIE) {
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MAINIRQMASK, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_E_IRQCAUSE, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_E_IRQMASK, 0);
|
||||
} else {
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MODE);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MODE, val & 0xff00ffff);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_DISCTIMER, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MSITRIGGER, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_XBARTIMEOUT, 0x000100ff);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MAINIRQMASK, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_SERRMASK, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_IRQCAUSE, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_IRQMASK, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_ERRLOWADDR, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_ERRHIGHADDR, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_ERRATTRIBUTE, 0);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_ERRCOMMAND, 0);
|
||||
}
|
||||
|
||||
/* Enable LED */
|
||||
if (sc->sc_gen == gen1) {
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_GPIOPORTCTL, 0);
|
||||
|
||||
/* XXXX: 50xxB2 errata ? */
|
||||
#if 0
|
||||
if (sc->sc_rev == 3) {
|
||||
int port;
|
||||
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_GPIOPORTCTL);
|
||||
|
||||
/* XXXX: check HDD connected */
|
||||
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_GPIOPORTCTL, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable Flash controller clock */
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_EROMBAR);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_EROMBAR, val & ~0x00000001);
|
||||
} else
|
||||
#if 0
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_GPIOPORTCTL, 0x00000060);
|
||||
#else /* XXXX */
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_GPIOPORTCTL, 0x00000070);
|
||||
#endif
|
||||
|
||||
if (sc->sc_flags & MVSATA_FLAGS_PCIE)
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_E_IRQMASK, 0x0000070a);
|
||||
else {
|
||||
val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MODE);
|
||||
if ((val & 0x30) >> 4) { /* PCI-X */
|
||||
int mv60x1b2 =
|
||||
((sc->sc_model == PCI_PRODUCT_MARVELL_88SX6041 ||
|
||||
sc->sc_model == PCI_PRODUCT_MARVELL_88SX6081) &&
|
||||
sc->sc_rev == 7);
|
||||
|
||||
pci_command &=
|
||||
~MVSATA_PCI_COMMAND_PCI_CONVENTIONAL_ONLY;
|
||||
if (sc->sc_gen == gen1 || mv60x1b2)
|
||||
pci_command &=
|
||||
~MVSATA_PCI_COMMAND_MWRITECOMBINE;
|
||||
} else
|
||||
if (sc->sc_gen == gen1)
|
||||
pci_command &=
|
||||
~(MVSATA_PCI_COMMAND_MWRITECOMBINE |
|
||||
MVSATA_PCI_COMMAND_MREADCOMBINE);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_COMMAND, pci_command);
|
||||
|
||||
#define MVSATA_PCI_INTERRUPT_MASK 0x00d77fe6
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_SERRMASK, MVSATA_PCI_INTERRUPT_MASK);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_IRQMASK, MVSATA_PCI_INTERRUPT_MASK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mvsata_pci_enable_intr(struct mvsata_port *mvport, int on)
|
||||
{
|
||||
struct mvsata_pci_softc *psc =
|
||||
device_private(mvport->port_ata_channel.ch_atac->atac_dev);
|
||||
uint32_t mask;
|
||||
int hc = mvport->port_hc->hc, port = mvport->port;
|
||||
|
||||
mask = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
|
||||
MVSATA_PCI_MAINIRQMASK);
|
||||
if (on)
|
||||
mask |= MVSATA_PCI_MAINIRQ_SATADONE(hc, port);
|
||||
else
|
||||
mask &= ~MVSATA_PCI_MAINIRQ_SATADONE(hc, port);
|
||||
bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINIRQMASK,
|
||||
mask);
|
||||
}
|
Loading…
Reference in New Issue