Import i386/gcscide(4). A driver for the IDE Controller of the

AMD CS5535 Companion device found in the decTOP.

gcscide0 at pci0 dev 15 function 2
gcscide0: National Semiconductor/AMD CS5535 IDE Controller (rev. 0x00)

Supports Ultra DMA mode 4, Pio Mode 4 and MDMA mode 2.

"Go for it" jmcneill@.
This commit is contained in:
xtraeme 2007-06-27 23:02:52 +00:00
parent dbbafa7889
commit a5ac7ff5aa
5 changed files with 315 additions and 4 deletions

View File

@ -1,4 +1,4 @@
LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.881 $>
LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.882 $>
[Note: This file does not mention every change made to the NetBSD source tree.
@ -144,3 +144,6 @@ Changes from NetBSD 4.0 to NetBSD 5.0:
tcpdrop(8): Ported by anon ymous (from FreeBSD/OpenBSD)
[christos 20070625]
fast_ipsec(4): Add support for IPsec NAT-T [degroote 20070627]
i386: Imported gcscide(4), a driver for the AMD CS5535 Companion
IDE Controller for systems with an AMD Geode GX2 CPU
(for example the decTOP). [xtraeme 20070627]

View File

@ -1,10 +1,10 @@
# $NetBSD: Makefile,v 1.66 2007/06/15 23:04:21 jmcneill Exp $
# $NetBSD: Makefile,v 1.67 2007/06/27 23:02:53 xtraeme Exp $
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
MAN= apm.4 autoconf.4 \
cmos.4 console.4 \
elansc.4 fdc.4 \
geodewdog.4 geodecntr.4 glxsb.4 gscpcib.4 \
gcscide.4 geodewdog.4 geodecntr.4 glxsb.4 gscpcib.4 \
intro.4 io.4 lms.4 lpt.4 mem.4 mms.4 npx.4 ndis.4 \
pcibios.4 pnpbios.4 sony.4 spic.4 vald.4 \
vesafb.4

View File

@ -0,0 +1,59 @@
.\" $NetBSD: gcscide.4,v 1.1 2007/06/27 23:02:53 xtraeme Exp $
.\"
.\" Copyright (c) 2003 Manuel Bouyer.
.\"
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Manuel Bouyer.
.\" 4. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission.
.\"
.\" 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 June 28, 2007
.Dt GCSCIDE 4
.Os
.Sh NAME
.Nm gcscide
.Nd AMD CS5535 Companion IDE controller driver
.Sh SYNOPSIS
.Cd "gcscide* at pci? dev ? function ? flags 0x0000"
.Sh DESCRIPTION
The
.Nm
driver supports the AMD CS5535 Companion IDE controller, and provides the
interface with the hardware for the
.Xr ata 4
driver.
.Pp
The 0x0002 flag forces the
.Nm
driver to disable DMA on chipsets for which DMA would normally be
enabled.
This can be used as a debugging aid, or to work around
problems where the IDE controller is wired up to the system incorrectly.
.Sh SEE ALSO
.Xr ata 4 ,
.Xr atapi 4 ,
.Xr intro 4 ,
.Xr pci 4 ,
.Xr pciide 4 ,
.Xr wd 4 ,
.Xr wdc 4

View File

@ -1,4 +1,4 @@
# $NetBSD: files.i386,v 1.309 2007/06/15 23:02:20 jmcneill Exp $
# $NetBSD: files.i386,v 1.310 2007/06/27 23:02:52 xtraeme Exp $
#
# new style config file for i386 architecture
#
@ -189,6 +189,11 @@ device elansc: sysmon_wdog, gpiobus
attach elansc at pci
file arch/i386/pci/elan520.c elansc
# AMD Geode CS5535 Companion IDE controller
device gcscide: ata, ata_dma, ata_udma, pciide_common, wdc_common
attach gcscide at pci
file arch/i386/pci/gcscide.c gcscide
# AMD Geode SC1100 GCB area
device geodegcb {}
attach geodegcb at pci

244
sys/arch/i386/pci/gcscide.c Normal file
View File

@ -0,0 +1,244 @@
/* $NetBSD: gcscide.c,v 1.1 2007/06/27 23:02:53 xtraeme Exp $ */
/*
* Copyright (c) 2007 The NetBSD Foundation.
* All rights reserved.
*
* This code is derived from software contributed to the NetBSD Foundation
* by Juan Romero Pardines.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Juan Romero Pardines
* for the NetBSD Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION OR CONTRIBUTORS
* 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.
*/
/*
* Driver for the National Semiconductor/AMD CS5535 Companion Controller.
* Usually this comes with an AMD Geode GX CPU.
*
* Datasheet at:
*
* http://www.amd.com/files/connectivitysolutions/geode/geode_gx/31506_cs5535_databook.pdf
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gcscide.c,v 1.1 2007/06/27 23:02:53 xtraeme Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <dev/pci/pciidereg.h>
#include <dev/pci/pciidevar.h>
#include <machine/cpufunc.h>
#define GCSCIDE_MSR_ATAC_BASE 0x51300000
#define GCSCIDE_ATAC_GLD_MSR_CAP (GCSCIDE_MSR_ATAC_BASE + 0)
#define GCSCIDE_ATAC_GLD_MSR_CONFIG (GCSCIDE_MSR_ATAC_BASE + 0x01)
#define GCSCIDE_ATAC_GLD_MSR_SMI (GCSCIDE_MSR_ATAC_BASE + 0x02)
#define GCSCIDE_ATAC_GLD_MSR_ERROR (GCSCIDE_MSR_ATAC_BASE + 0x03)
#define GCSCIDE_ATAC_GLD_MSR_PM (GCSCIDE_MSR_ATAC_BASE + 0x04)
#define GCSCIDE_ATAC_GLD_MSR_DIAG (GCSCIDE_MSR_ATAC_BASE + 0x05)
#define GCSCIDE_ATAC_IO_BAR (GCSCIDE_MSR_ATAC_BASE + 0x08)
#define GCSCIDE_ATAC_RESET (GCSCIDE_MSR_ATAC_BASE + 0x10)
#define GCSCIDE_ATAC_CH0D0_PIO (GCSCIDE_MSR_ATAC_BASE + 0x20)
#define GCSCIDE_ATAC_CH0D0_DMA (GCSCIDE_MSR_ATAC_BASE + 0x21)
#define GCSCIDE_ATAC_CH0D1_PIO (GCSCIDE_MSR_ATAC_BASE + 0x22)
#define GCSCIDE_ATAC_CH0D1_DMA (GCSCIDE_MSR_ATAC_BASE + 0x23)
#define GCSCIDE_ATAC_PCI_ABRTERR (GCSCIDE_MSR_ATAC_BASE + 0x24)
#define GCSCIDE_ATAC_BM0_CMD_PRIM 0x00
#define GCSCIDE_ATAC_BM0_STS_PRIM 0x02
#define GCSCIDE_ATAC_BM0_PRD 0x04
#define GCSCIDE_PIO_FORMAT 0x80000000UL
static int gcscide_match(struct device *, struct cfdata *, void *);
static void gcscide_attach(struct device *, struct device *, void *);
static void gcscide_chip_map(struct pciide_softc *, struct pci_attach_args *);
static void gcscide_setup_channel(struct ata_channel *);
/* PIO Format 1 timings */
static const uint32_t gcscide_pio_timings[] = {
0xf7f4f7f4, /* PIO Mode 0 */
0x53f3f173, /* PIO Mode 1 */
0x13f18141, /* PIO Mode 2 */
0x51315131, /* PIO Mode 3 */
0x11311131 /* PIO Mode 4 */
};
static const uint32_t gcscide_mdma_timings[] = {
0x7f0ffff3, /* MDMA Mode 0 */
0x7f035352, /* MDMA Mode 1 */
0x7f024241 /* MDMA Mode 2 */
};
static const uint32_t gcscide_udma_timings[] = {
0x7f7436a1, /* Ultra DMA Mode 0 */
0x7f733481, /* Ultra DMA Mode 1 */
0x7f723261, /* Ultra DMA Mode 2 */
0x7f713161, /* Ultra DMA Mode 3 */
0x7f703061 /* Ultra DMA Mode 4 */
};
CFATTACH_DECL(gcscide, sizeof(struct pciide_softc),
gcscide_match, gcscide_attach, NULL, NULL);
static const struct pciide_product_desc pciide_gcscide_products[] = {
{
PCI_PRODUCT_NS_CS5535_IDE,
0,
"National Semiconductor/AMD CS5535 IDE Controller",
gcscide_chip_map
},
{ 0, 0, NULL, NULL }
};
static int
gcscide_match(struct device *parent, struct cfdata *cfdata, void *aux)
{
struct pci_attach_args *pa = (struct pci_attach_args *)aux;
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NS &&
PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE &&
PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE &&
pciide_lookup_product(pa->pa_id, pciide_gcscide_products))
return 2;
return 0;
}
static void
gcscide_attach(struct device *parent, struct device *self, void *aux)
{
struct pci_attach_args *pa = aux;
struct pciide_softc *sc = (struct pciide_softc *)self;
pciide_common_attach(sc, pa,
pciide_lookup_product(pa->pa_id, pciide_gcscide_products));
}
static void
gcscide_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
{
pcireg_t interface;
bus_size_t cmdsize, ctlsize;
if (pciide_chipen(sc, pa) == 0)
return;
aprint_verbose("%s: bus-master DMA support present",
sc->sc_wdcdev.sc_atac.atac_dev.dv_xname);
pciide_mapreg_dma(sc, pa);
aprint_verbose("\n");
sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
if (sc->sc_dma_ok) {
sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA;
sc->sc_wdcdev.irqack = pciide_irqack;
}
sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
sc->sc_wdcdev.sc_atac.atac_udma_cap = 4;
sc->sc_wdcdev.sc_atac.atac_set_modes = gcscide_setup_channel;
sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
sc->sc_wdcdev.sc_atac.atac_nchannels = 1;
interface = PCI_INTERFACE(pa->pa_class);
wdc_allocate_regs(&sc->sc_wdcdev);
if (pciide_chansetup(sc, 0, interface) == 0)
return;
pciide_mapchan(pa, &sc->pciide_channels[0], interface,
&cmdsize, &ctlsize, pciide_pci_intr);
}
static void
gcscide_setup_channel(struct ata_channel *chp)
{
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct ata_drive_datas *drvp;
uint64_t reg = 0;
int drive, s;
pciide_channel_dma_setup(cp);
for (drive = 0; drive < 2; drive++) {
drvp = &chp->ch_drive[drive];
if ((drvp->drive_flags & DRIVE) == 0)
continue;
if ((drvp->drive_flags & DRIVE_UDMA) ||
(drvp->drive_flags & DRIVE_DMA)) {
reg = rdmsr(drive ? GCSCIDE_ATAC_CH0D1_DMA :
GCSCIDE_ATAC_CH0D0_DMA);
/* high 32 bits */
reg = (reg << 32);
/* Preserve PIO Format bit */
reg &= GCSCIDE_PIO_FORMAT;
}
if (drvp->drive_flags & DRIVE_UDMA) {
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
/* Set UDMA and MDMA timings */
reg |= gcscide_udma_timings[drvp->UDMA_mode];
reg |= gcscide_mdma_timings[drvp->DMA_mode];
wrmsr(drive ? GCSCIDE_ATAC_CH0D1_DMA :
GCSCIDE_ATAC_CH0D0_DMA, reg);
} else if (drvp->drive_flags & DRIVE_DMA) {
/*
* Disable Ultra DMA and set a MDMA mode.
*/
if (reg & gcscide_udma_timings[drvp->UDMA_mode])
reg &= ~gcscide_udma_timings[drvp->UDMA_mode];
reg |= gcscide_mdma_timings[drvp->DMA_mode];
wrmsr(drive ? GCSCIDE_ATAC_CH0D1_DMA :
GCSCIDE_ATAC_CH0D0_DMA, reg);
} else {
/*
* Set PIO Format 1 timings.
*/
reg = rdmsr(drive ? GCSCIDE_ATAC_CH0D1_DMA :
GCSCIDE_ATAC_CH0D0_DMA);
reg = (reg << 32);
wrmsr(drive ? GCSCIDE_ATAC_CH0D1_DMA :
GCSCIDE_ATAC_CH0D0_DMA, reg | GCSCIDE_PIO_FORMAT);
}
/* Set PIO mode and timing */
wrmsr(drive ? GCSCIDE_ATAC_CH0D1_PIO : GCSCIDE_ATAC_CH0D1_PIO,
gcscide_pio_timings[drvp->PIO_mode]);
}
}