OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [ata/] [sata_sis.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  sata_sis.c - Silicon Integrated Systems SATA
3
 *
4
 *  Maintained by:  Uwe Koziolek
5
 *                  Please ALWAYS copy linux-ide@vger.kernel.org
6
 *                  on emails.
7
 *
8
 *  Copyright 2004 Uwe Koziolek
9
 *
10
 *
11
 *  This program is free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2, or (at your option)
14
 *  any later version.
15
 *
16
 *  This program is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this program; see the file COPYING.  If not, write to
23
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24
 *
25
 *
26
 *  libata documentation is available via 'make {ps|pdf}docs',
27
 *  as Documentation/DocBook/libata.*
28
 *
29
 *  Hardware documentation available under NDA.
30
 *
31
 */
32
 
33
#include <linux/kernel.h>
34
#include <linux/module.h>
35
#include <linux/pci.h>
36
#include <linux/init.h>
37
#include <linux/blkdev.h>
38
#include <linux/delay.h>
39
#include <linux/interrupt.h>
40
#include <linux/device.h>
41
#include <scsi/scsi_host.h>
42
#include <linux/libata.h>
43
#include "sis.h"
44
 
45
#define DRV_NAME        "sata_sis"
46
#define DRV_VERSION     "1.0"
47
 
48
enum {
49
        sis_180                 = 0,
50
        SIS_SCR_PCI_BAR         = 5,
51
 
52
        /* PCI configuration registers */
53
        SIS_GENCTL              = 0x54, /* IDE General Control register */
54
        SIS_SCR_BASE            = 0xc0, /* sata0 phy SCR registers */
55
        SIS180_SATA1_OFS        = 0x10, /* offset from sata0->sata1 phy regs */
56
        SIS182_SATA1_OFS        = 0x20, /* offset from sata0->sata1 phy regs */
57
        SIS_PMR                 = 0x90, /* port mapping register */
58
        SIS_PMR_COMBINED        = 0x30,
59
 
60
        /* random bits */
61
        SIS_FLAG_CFGSCR         = (1 << 30), /* host flag: SCRs via PCI cfg */
62
 
63
        GENCTL_IOMAPPED_SCR     = (1 << 26), /* if set, SCRs are in IO space */
64
};
65
 
66
static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
67
static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
68
static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
69
 
70
static const struct pci_device_id sis_pci_tbl[] = {
71
        { PCI_VDEVICE(SI, 0x0180), sis_180 },   /* SiS 964/180 */
72
        { PCI_VDEVICE(SI, 0x0181), sis_180 },   /* SiS 964/180 */
73
        { PCI_VDEVICE(SI, 0x0182), sis_180 },   /* SiS 965/965L */
74
        { PCI_VDEVICE(SI, 0x0183), sis_180 },   /* SiS 965/965L */
75
        { PCI_VDEVICE(SI, 0x1182), sis_180 },   /* SiS 966/680 */
76
        { PCI_VDEVICE(SI, 0x1183), sis_180 },   /* SiS 966/966L/968/680 */
77
 
78
        { }     /* terminate list */
79
};
80
 
81
static struct pci_driver sis_pci_driver = {
82
        .name                   = DRV_NAME,
83
        .id_table               = sis_pci_tbl,
84
        .probe                  = sis_init_one,
85
        .remove                 = ata_pci_remove_one,
86
};
87
 
88
static struct scsi_host_template sis_sht = {
89
        .module                 = THIS_MODULE,
90
        .name                   = DRV_NAME,
91
        .ioctl                  = ata_scsi_ioctl,
92
        .queuecommand           = ata_scsi_queuecmd,
93
        .can_queue              = ATA_DEF_QUEUE,
94
        .this_id                = ATA_SHT_THIS_ID,
95
        .sg_tablesize           = LIBATA_MAX_PRD,
96
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
97
        .emulated               = ATA_SHT_EMULATED,
98
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
99
        .proc_name              = DRV_NAME,
100
        .dma_boundary           = ATA_DMA_BOUNDARY,
101
        .slave_configure        = ata_scsi_slave_config,
102
        .slave_destroy          = ata_scsi_slave_destroy,
103
        .bios_param             = ata_std_bios_param,
104
};
105
 
106
static const struct ata_port_operations sis_ops = {
107
        .tf_load                = ata_tf_load,
108
        .tf_read                = ata_tf_read,
109
        .check_status           = ata_check_status,
110
        .exec_command           = ata_exec_command,
111
        .dev_select             = ata_std_dev_select,
112
        .bmdma_setup            = ata_bmdma_setup,
113
        .bmdma_start            = ata_bmdma_start,
114
        .bmdma_stop             = ata_bmdma_stop,
115
        .bmdma_status           = ata_bmdma_status,
116
        .qc_prep                = ata_qc_prep,
117
        .qc_issue               = ata_qc_issue_prot,
118
        .data_xfer              = ata_data_xfer,
119
        .freeze                 = ata_bmdma_freeze,
120
        .thaw                   = ata_bmdma_thaw,
121
        .error_handler          = ata_bmdma_error_handler,
122
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
123
        .irq_clear              = ata_bmdma_irq_clear,
124
        .irq_on                 = ata_irq_on,
125
        .scr_read               = sis_scr_read,
126
        .scr_write              = sis_scr_write,
127
        .port_start             = ata_port_start,
128
};
129
 
130
static const struct ata_port_info sis_port_info = {
131
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
132
        .pio_mask       = 0x1f,
133
        .mwdma_mask     = 0x7,
134
        .udma_mask      = ATA_UDMA6,
135
        .port_ops       = &sis_ops,
136
};
137
 
138
MODULE_AUTHOR("Uwe Koziolek");
139
MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
140
MODULE_LICENSE("GPL");
141
MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
142
MODULE_VERSION(DRV_VERSION);
143
 
144
static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
145
{
146
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
147
        unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
148
        u8 pmr;
149
 
150
        if (ap->port_no)  {
151
                switch (pdev->device) {
152
                case 0x0180:
153
                case 0x0181:
154
                        pci_read_config_byte(pdev, SIS_PMR, &pmr);
155
                        if ((pmr & SIS_PMR_COMBINED) == 0)
156
                                addr += SIS180_SATA1_OFS;
157
                        break;
158
 
159
                case 0x0182:
160
                case 0x0183:
161
                case 0x1182:
162
                        addr += SIS182_SATA1_OFS;
163
                        break;
164
                }
165
        }
166
        return addr;
167
}
168
 
169
static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
170
{
171
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
172
        unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
173
        u32 val2 = 0;
174
        u8 pmr;
175
 
176
        if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
177
                return 0xffffffff;
178
 
179
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
180
 
181
        pci_read_config_dword(pdev, cfg_addr, val);
182
 
183
        if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
184
            (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
185
                pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
186
 
187
        *val |= val2;
188
        *val &= 0xfffffffb;     /* avoid problems with powerdowned ports */
189
 
190
        return 0;
191
}
192
 
193
static void sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
194
{
195
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
196
        unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
197
        u8 pmr;
198
 
199
        if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
200
                return;
201
 
202
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
203
 
204
        pci_write_config_dword(pdev, cfg_addr, val);
205
 
206
        if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
207
            (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
208
                pci_write_config_dword(pdev, cfg_addr+0x10, val);
209
}
210
 
211
static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
212
{
213
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
214
        u8 pmr;
215
 
216
        if (sc_reg > SCR_CONTROL)
217
                return -EINVAL;
218
 
219
        if (ap->flags & SIS_FLAG_CFGSCR)
220
                return sis_scr_cfg_read(ap, sc_reg, val);
221
 
222
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
223
 
224
        *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
225
 
226
        if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
227
            (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
228
                *val |= ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
229
 
230
        *val &= 0xfffffffb;
231
 
232
        return 0;
233
}
234
 
235
static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
236
{
237
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
238
        u8 pmr;
239
 
240
        if (sc_reg > SCR_CONTROL)
241
                return -EINVAL;
242
 
243
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
244
 
245
        if (ap->flags & SIS_FLAG_CFGSCR)
246
                sis_scr_cfg_write(ap, sc_reg, val);
247
        else {
248
                iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
249
                if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
250
                    (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
251
                        iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10);
252
        }
253
        return 0;
254
}
255
 
256
static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
257
{
258
        static int printed_version;
259
        struct ata_port_info pi = sis_port_info;
260
        const struct ata_port_info *ppi[] = { &pi, &pi };
261
        struct ata_host *host;
262
        u32 genctl, val;
263
        u8 pmr;
264
        u8 port2_start = 0x20;
265
        int rc;
266
 
267
        if (!printed_version++)
268
                dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
269
 
270
        rc = pcim_enable_device(pdev);
271
        if (rc)
272
                return rc;
273
 
274
        /* check and see if the SCRs are in IO space or PCI cfg space */
275
        pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
276
        if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
277
                pi.flags |= SIS_FLAG_CFGSCR;
278
 
279
        /* if hardware thinks SCRs are in IO space, but there are
280
         * no IO resources assigned, change to PCI cfg space.
281
         */
282
        if ((!(pi.flags & SIS_FLAG_CFGSCR)) &&
283
            ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) ||
284
             (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) {
285
                genctl &= ~GENCTL_IOMAPPED_SCR;
286
                pci_write_config_dword(pdev, SIS_GENCTL, genctl);
287
                pi.flags |= SIS_FLAG_CFGSCR;
288
        }
289
 
290
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
291
        switch (ent->device) {
292
        case 0x0180:
293
        case 0x0181:
294
 
295
                /* The PATA-handling is provided by pata_sis */
296
                switch (pmr & 0x30) {
297
                case 0x10:
298
                        ppi[1] = &sis_info133_for_sata;
299
                        break;
300
 
301
                case 0x30:
302
                        ppi[0] = &sis_info133_for_sata;
303
                        break;
304
                }
305
                if ((pmr & SIS_PMR_COMBINED) == 0) {
306
                        dev_printk(KERN_INFO, &pdev->dev,
307
                                   "Detected SiS 180/181/964 chipset in SATA mode\n");
308
                        port2_start = 64;
309
                } else {
310
                        dev_printk(KERN_INFO, &pdev->dev,
311
                                   "Detected SiS 180/181 chipset in combined mode\n");
312
                        port2_start = 0;
313
                        pi.flags |= ATA_FLAG_SLAVE_POSS;
314
                }
315
                break;
316
 
317
        case 0x0182:
318
        case 0x0183:
319
                pci_read_config_dword(pdev, 0x6C, &val);
320
                if (val & (1L << 31)) {
321
                        dev_printk(KERN_INFO, &pdev->dev,
322
                                   "Detected SiS 182/965 chipset\n");
323
                        pi.flags |= ATA_FLAG_SLAVE_POSS;
324
                } else {
325
                        dev_printk(KERN_INFO, &pdev->dev,
326
                                   "Detected SiS 182/965L chipset\n");
327
                }
328
                break;
329
 
330
        case 0x1182:
331
                dev_printk(KERN_INFO, &pdev->dev,
332
                           "Detected SiS 1182/966/680 SATA controller\n");
333
                pi.flags |= ATA_FLAG_SLAVE_POSS;
334
                break;
335
 
336
        case 0x1183:
337
                dev_printk(KERN_INFO, &pdev->dev,
338
                           "Detected SiS 1183/966/966L/968/680 controller in PATA mode\n");
339
                ppi[0] = &sis_info133_for_sata;
340
                ppi[1] = &sis_info133_for_sata;
341
                break;
342
        }
343
 
344
        rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
345
        if (rc)
346
                return rc;
347
 
348
        if (!(pi.flags & SIS_FLAG_CFGSCR)) {
349
                void __iomem *mmio;
350
 
351
                rc = pcim_iomap_regions(pdev, 1 << SIS_SCR_PCI_BAR, DRV_NAME);
352
                if (rc)
353
                        return rc;
354
                mmio = host->iomap[SIS_SCR_PCI_BAR];
355
 
356
                host->ports[0]->ioaddr.scr_addr = mmio;
357
                host->ports[1]->ioaddr.scr_addr = mmio + port2_start;
358
        }
359
 
360
        pci_set_master(pdev);
361
        pci_intx(pdev, 1);
362
        return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
363
                                 &sis_sht);
364
}
365
 
366
static int __init sis_init(void)
367
{
368
        return pci_register_driver(&sis_pci_driver);
369
}
370
 
371
static void __exit sis_exit(void)
372
{
373
        pci_unregister_driver(&sis_pci_driver);
374
}
375
 
376
module_init(sis_init);
377
module_exit(sis_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.