linux/drivers/ata/pata_cs5535.c
<<
>>
Prefs
   1/*
   2 * pata-cs5535.c        - CS5535 PATA for new ATA layer
   3 *                        (C) 2005-2006 Red Hat Inc
   4 *                        Alan Cox <alan@lxorguk.ukuu.org.uk>
   5 *
   6 * based upon cs5535.c from AMD <Jens.Altmann@amd.com> as cleaned up and
   7 * made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
   8 * and Alexander Kiausch <alex.kiausch@t-online.de>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  22 *
  23 * Loosely based on the piix & svwks drivers.
  24 *
  25 * Documentation:
  26 *      Available from AMD web site.
  27 * TODO
  28 *      Review errata to see if serializing is necessary
  29 */
  30
  31#include <linux/kernel.h>
  32#include <linux/module.h>
  33#include <linux/pci.h>
  34#include <linux/init.h>
  35#include <linux/blkdev.h>
  36#include <linux/delay.h>
  37#include <scsi/scsi_host.h>
  38#include <linux/libata.h>
  39#include <asm/msr.h>
  40
  41#define DRV_NAME        "pata_cs5535"
  42#define DRV_VERSION     "0.2.12"
  43
  44/*
  45 *      The Geode (Aka Athlon GX now) uses an internal MSR based
  46 *      bus system for control. Demented but there you go.
  47 */
  48
  49#define MSR_ATAC_BASE           0x51300000
  50#define ATAC_GLD_MSR_CAP        (MSR_ATAC_BASE+0)
  51#define ATAC_GLD_MSR_CONFIG    (MSR_ATAC_BASE+0x01)
  52#define ATAC_GLD_MSR_SMI       (MSR_ATAC_BASE+0x02)
  53#define ATAC_GLD_MSR_ERROR     (MSR_ATAC_BASE+0x03)
  54#define ATAC_GLD_MSR_PM        (MSR_ATAC_BASE+0x04)
  55#define ATAC_GLD_MSR_DIAG      (MSR_ATAC_BASE+0x05)
  56#define ATAC_IO_BAR            (MSR_ATAC_BASE+0x08)
  57#define ATAC_RESET             (MSR_ATAC_BASE+0x10)
  58#define ATAC_CH0D0_PIO         (MSR_ATAC_BASE+0x20)
  59#define ATAC_CH0D0_DMA         (MSR_ATAC_BASE+0x21)
  60#define ATAC_CH0D1_PIO         (MSR_ATAC_BASE+0x22)
  61#define ATAC_CH0D1_DMA         (MSR_ATAC_BASE+0x23)
  62#define ATAC_PCI_ABRTERR       (MSR_ATAC_BASE+0x24)
  63
  64#define ATAC_BM0_CMD_PRIM      0x00
  65#define ATAC_BM0_STS_PRIM      0x02
  66#define ATAC_BM0_PRD           0x04
  67
  68#define CS5535_CABLE_DETECT    0x48
  69
  70/**
  71 *      cs5535_cable_detect     -       detect cable type
  72 *      @ap: Port to detect on
  73 *
  74 *      Perform cable detection for ATA66 capable cable. Return a libata
  75 *      cable type.
  76 */
  77
  78static int cs5535_cable_detect(struct ata_port *ap)
  79{
  80        u8 cable;
  81        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  82
  83        pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable);
  84        if (cable & 1)
  85                return ATA_CBL_PATA80;
  86        else
  87                return ATA_CBL_PATA40;
  88}
  89
  90/**
  91 *      cs5535_set_piomode              -       PIO setup
  92 *      @ap: ATA interface
  93 *      @adev: device on the interface
  94 *
  95 *      Set our PIO requirements. The CS5535 is pretty clean about all this
  96 */
  97
  98static void cs5535_set_piomode(struct ata_port *ap, struct ata_device *adev)
  99{
 100        static const u16 pio_timings[5] = {
 101                0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131
 102        };
 103        static const u16 pio_cmd_timings[5] = {
 104                0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131
 105        };
 106        u32 reg, dummy;
 107        struct ata_device *pair = ata_dev_pair(adev);
 108
 109        int mode = adev->pio_mode - XFER_PIO_0;
 110        int cmdmode = mode;
 111
 112        /* Command timing has to be for the lowest of the pair of devices */
 113        if (pair) {
 114                int pairmode = pair->pio_mode - XFER_PIO_0;
 115                cmdmode = min(mode, pairmode);
 116                /* Write the other drive timing register if it changed */
 117                if (cmdmode < pairmode)
 118                        wrmsr(ATAC_CH0D0_PIO + 2 * pair->devno,
 119                                pio_cmd_timings[cmdmode] << 16 | pio_timings[pairmode], 0);
 12> = pair->  12/lass="sref">wrmsr(ATAC_CH0D0_PIO + 2 * paiv->,
  23="sref">pio_cmd_timings[cmdmode] << 16 | pio_timings[,   24pata_cs5535.c#L120" id="L120" class="line" name="L25">  25  26u32(ATAC_CH0D0_DMA         (paiv->,
reg, dummy;
  27/lass="sref">wrmsr(ATAC_CH0D0_DMA         (paiv->,
reg,   28  29  30
/**
  31#include &1lt; *      cs5535_set_piomode              -dma    PIO setup
  32#include &1lt; *      @ap: ATA interface
  13 *      @adev: device on the interfacD  34#include &1lt; *
  35#include &1lt; *      Set our PIO requers/ata/pata_cs5535.c#L117" id="L117" class="lne" name=1"L36">  36#include &1lt;  37#include &1lt;dma    set_piomode(struct ata_port *ap, struct ata_device *adev)
  38#include &1lt;  39#include &1lt;u16 regpio_timings[pio_timrivers/ata/pata_cs5535.c#L104" id="L104" class="lne" name=1"L40">  40
  41#define   42#define u16 regpio_timings[pio_timriver3/ata/pata_cs5535.c#L104" id="L104" class="lne" name=""L43">  43
  14  45/lass="sref">wr/a> reg, dummy;
  46mode = adev->e =   47  48
/lass="sref">wrrdr(ATAC_CH0D0_DMA         (paiv->,
reg, dummy;
  49#define /lass="sref">wrra>,   50#define e = adef="drUef=PIO_0;
  51#define reg, adeudma>pio_timings[pio_timriver" class="sref">e = XFUef=PIO_0;
  52#define   53#define /a>, ademwdma>pio_timings[pio_timriver" class="sref">e = XFMW_ef=PIO_0;
  54#define /lass="sref">wrmsr(ATAC_CH0D0_DMA         (paiv->,
reg,   55#define   56#define   57#define reg<(struct h_cable_detect(struc h_adev" c/pata_cs5535.c#L104" id="L104" class="lne" name=1"L58">  58#define /lass="sref">wr hreBMef=PSHESET           eBMef=PSHEAC_CH0D0_PIO" class=>DRV_NAME          59#define   60#define   61#define [reg<(structde=a_opmings[  62#define reg[ca"L10bmdma>de=a_opmings[de=a_opm/ata/pata_cs5535.c#L119" id="L119" class="lne" name=1"L63">  63
regcs5535_cable_detect reg<(structref">cs5535_cable_detect(struct   64#define regcs5535_set_piomode reg<(structef">cs5535_set_piomode(struct   65#define regdma    set_piomode reg<(structef">dma    set_piomode(struct   16  67
  68#define  *      Review errata ivers/ata/pata_cs5535.c#L91" id="L91" class="li1ne" name=1"L69">  69
 * You should have receivvvvvv(struct="dr_on PIO setupn>
  70/**
  71 *      cs5535_cable_detect   @id: Entryhll match tref="d/ata/pata_cs5535.c#L17" id="L17" class="linee" name=1"L72">  72 *      @ap: Port to det"d/ata/pata_cs5535.c#L17" id="L17" class="linee" name=1"L73">  73 *
  74 *      Perform cable detectiowriteitejuceshousekeep_ti. Weof theis ne. cod1chip="drcorr="+ly ivers/ata/pata_cs5535.c#L7" id="L7" class="line1ne" name=1"L75">  75 *      cable type.
  76 */
  77
  78static int1 (struct="dr_on code=ata_port" class="sref"pci_dev *pde/a>);
 *pdeid *  79{
  80        ,
reg,
  81        st1ruct 18xF7F4, 0xF173, 0x8141.ass="sref">reg[ade   eFLAG_SLAVE_POSSSET           eFLAG_SLAVE_POSScode/pata_cs5535.c#L119" id="L119" class="lne" name=1"L82">  82
reg<="+coask *ade   ePIO4SET           ePIO4code/pata_cs5535.c#L119" id="L119" class="lne" name=1"L83">  83        regoask *ade   eMWDMA>   84        if1 (regoask *ade   eUef=4SET           eUef=4code/pata_cs5535.c#L119" id="L119" class="lne" name=1"L85">  85          1     1return reg<=e=a_opmings[cabstructde=a_opmings[  86        el1se
  87          1     1return ,
pairpiings[cainf/a>,
caf="+cversode=a_inf/a>,
  18  89
ATA_CBL_PATA40" class="+codcodbmdma>="dr_on set_piomode"+codcodbmdma>="dr_on AC_CH0D0_PIO" class=/a>);
pairpiings[cabstruct h_cable_detect(struc h_adev,ulass="sref">paiNULLcable_detect  90/pata_cs5535.c#L89" id="L89" class="li1ne" name=1"L91">  91  92+code=u16" clata_device" class="srepci_deve=a_id *cabstruccable_detect(struriver/ata/pata_cs5535.c#L112" id="L112" class="lne" name=1"L93">  93ca(                NSadev,ulass="sref">pai(, &IDME        , &IDMs="s)/ }/pata_cs5535.c#L119" id="L119" class="lne" name=1"L94">  94ca(               MDadev,ulass="sref">pai(, &IDME        , &IDMs="s)/ }/pata_cs5535.c#L119" id="L119" class="lne" name=1"L95">  95pata_cs5535.c#L119" id="L119" class="lne" name=1"L96">  96  97
  98static voi1d   99{
reg<(structdcode.c#L1 * 100        s2atic 2onst reg<     *ade>DRV_NAME         101         2     20xF7F4, 0xF173.ass="sref">reg & 1)
cabstruccable_detect(strurive/pata_cs5535.c#L119" id="L119" class="2ie" name=""L102"> 102        }2
reg], 0);
reg<(struct="dr_on set_piomode(struct="dr_on code/pata_cs5535.c#L119" id="L119" class="2ie" name=""L103"> 103        s2atic 203            .ass="sref">regremov turn ("+codcoda mov _on code/pata_cs5535.c#L119" id="L119" class="2ie" name=""L104"> 104         2     20ref="infdef_CABLE_DETECT" cl"+cod_GLD_MSR_PM   l"+cod_GLata/pata_cs5535.c#L109" id="L109" class="2ine" name2"L105"> 105        }2
reg *( *( 106        <2 href2"+code=u32" cl.ass="sref">reg *( *( 107        s2ruct 2a href#endifpata_cs5535.c#L119" id="L119" class="2ie" name=""L108"> 108
 109        i2t  110        i2t e * * 111
 112        <2pan c2ass="c0D0_PIO" class=MODULE_AUTHGLD_MSR_ERRORMODULE_AUTHGLAC_CH0uot;0.2.12"
 113        i2 (     
 114         2     2int +0x24)ODULE_LICMNTAAC_CH0uot;0.2.12"
 115         2     2      *paibstruccable_detect(strurivea/pata_cs5535.c#L120" id="L120" class="2ie" name=""L116"> 116         2     2     DRVDRV_VERSION      117         2     2if (


117footL1<> leanorigia hrLXR software byr of ata_cs553http://sourcepaige.net/projects/lx1<>LXR hreu"dryadev,uwriteexperief=" hr#L12riv byrata_cs553mailto:lx1@lx1@ 117subfootL1<> lx1.Redpill L/apro ASadev,uprovider of L/auxu16" ultngedor toper"drivm serf="drisincev1rs5.