blob: ff614be55d0f5838b6c8ca46a00027f6d6e04c40 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * sata_svw.c - ServerWorks / Apple K2 SATA
3 *
4 * Maintained by: Benjamin Herrenschmidt <benh@kernel.crashing.org> and
5 * Jeff Garzik <jgarzik@pobox.com>
6 * Please ALWAYS copy linux-ide@vger.kernel.org
7 * on emails.
8 *
9 * Copyright 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
10 *
11 * Bits from Jeff Garzik, Copyright RedHat, Inc.
12 *
13 * This driver probably works with non-Apple versions of the
14 * Broadcom chipset...
15 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 *
Jeff Garzikaf36d7f2005-08-28 20:18:39 -040017 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2, or (at your option)
20 * any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; see the file COPYING. If not, write to
29 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 *
31 *
32 * libata documentation is available via 'make {ps|pdf}docs',
33 * as Documentation/DocBook/libata.*
34 *
35 * Hardware documentation available under NDA.
Linus Torvalds1da177e2005-04-16 15:20:36 -070036 *
37 */
38
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#include <linux/kernel.h>
40#include <linux/module.h>
41#include <linux/pci.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <linux/blkdev.h>
43#include <linux/delay.h>
44#include <linux/interrupt.h>
Jeff Garzika9524a72005-10-30 14:39:11 -050045#include <linux/device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070046#include <scsi/scsi_host.h>
Anantha Subramanyam931506d2008-02-28 15:58:35 -080047#include <scsi/scsi_cmnd.h>
48#include <scsi/scsi.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <linux/libata.h>
Kevin Haod610f502015-03-12 20:32:42 +080050#include <linux/of.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
52#define DRV_NAME "sata_svw"
Jeff Garzik2a3103c2007-08-31 04:54:06 -040053#define DRV_VERSION "2.3"
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Jeff Garzik55cca652006-03-21 22:14:17 -050055enum {
Tejun Heo4447d352007-04-17 23:44:08 +090056 /* ap->flags bits */
57 K2_FLAG_SATA_8_PORTS = (1 << 24),
58 K2_FLAG_NO_ATAPI_DMA = (1 << 25),
Anantha Subramanyam931506d2008-02-28 15:58:35 -080059 K2_FLAG_BAR_POS_3 = (1 << 26),
Jeff Garzikc10340a2006-12-14 17:04:33 -050060
Jeff Garzik55cca652006-03-21 22:14:17 -050061 /* Taskfile registers offsets */
62 K2_SATA_TF_CMD_OFFSET = 0x00,
63 K2_SATA_TF_DATA_OFFSET = 0x00,
64 K2_SATA_TF_ERROR_OFFSET = 0x04,
65 K2_SATA_TF_NSECT_OFFSET = 0x08,
66 K2_SATA_TF_LBAL_OFFSET = 0x0c,
67 K2_SATA_TF_LBAM_OFFSET = 0x10,
68 K2_SATA_TF_LBAH_OFFSET = 0x14,
69 K2_SATA_TF_DEVICE_OFFSET = 0x18,
70 K2_SATA_TF_CMDSTAT_OFFSET = 0x1c,
71 K2_SATA_TF_CTL_OFFSET = 0x20,
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
Jeff Garzik55cca652006-03-21 22:14:17 -050073 /* DMA base */
74 K2_SATA_DMA_CMD_OFFSET = 0x30,
Linus Torvalds1da177e2005-04-16 15:20:36 -070075
Jeff Garzik55cca652006-03-21 22:14:17 -050076 /* SCRs base */
77 K2_SATA_SCR_STATUS_OFFSET = 0x40,
78 K2_SATA_SCR_ERROR_OFFSET = 0x44,
79 K2_SATA_SCR_CONTROL_OFFSET = 0x48,
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
Jeff Garzik55cca652006-03-21 22:14:17 -050081 /* Others */
82 K2_SATA_SICR1_OFFSET = 0x80,
83 K2_SATA_SICR2_OFFSET = 0x84,
84 K2_SATA_SIM_OFFSET = 0x88,
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
Jeff Garzik55cca652006-03-21 22:14:17 -050086 /* Port stride */
87 K2_SATA_PORT_OFFSET = 0x100,
Jeff Garzikc10340a2006-12-14 17:04:33 -050088
Anantha Subramanyam931506d2008-02-28 15:58:35 -080089 chip_svw4 = 0,
90 chip_svw8 = 1,
91 chip_svw42 = 2, /* bar 3 */
92 chip_svw43 = 3, /* bar 5 */
Jeff Garzikc10340a2006-12-14 17:04:33 -050093};
94
Jeff Garzikac19bff2005-10-29 13:58:21 -040095static u8 k2_stat_check_status(struct ata_port *ap);
96
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Jeff Garzikc10340a2006-12-14 17:04:33 -050098static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
99{
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800100 u8 cmnd = qc->scsicmd->cmnd[0];
101
Jeff Garzikc10340a2006-12-14 17:04:33 -0500102 if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
103 return -1; /* ATAPI DMA not supported */
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800104 else {
105 switch (cmnd) {
106 case READ_10:
107 case READ_12:
108 case READ_16:
109 case WRITE_10:
110 case WRITE_12:
111 case WRITE_16:
112 return 0;
Jeff Garzikc10340a2006-12-14 17:04:33 -0500113
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800114 default:
115 return -1;
116 }
117
118 }
Jeff Garzikc10340a2006-12-14 17:04:33 -0500119}
120
Tejun Heo82ef04f2008-07-31 17:02:40 +0900121static int k2_sata_scr_read(struct ata_link *link,
122 unsigned int sc_reg, u32 *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123{
124 if (sc_reg > SCR_CONTROL)
Tejun Heoda3dbb12007-07-16 14:29:40 +0900125 return -EINVAL;
Tejun Heo82ef04f2008-07-31 17:02:40 +0900126 *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
Tejun Heoda3dbb12007-07-16 14:29:40 +0900127 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128}
129
130
Tejun Heo82ef04f2008-07-31 17:02:40 +0900131static int k2_sata_scr_write(struct ata_link *link,
132 unsigned int sc_reg, u32 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
134 if (sc_reg > SCR_CONTROL)
Tejun Heoda3dbb12007-07-16 14:29:40 +0900135 return -EINVAL;
Tejun Heo82ef04f2008-07-31 17:02:40 +0900136 writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
Tejun Heoda3dbb12007-07-16 14:29:40 +0900137 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138}
139
David Milburnb03e66a2012-10-29 18:00:22 -0500140static int k2_sata_softreset(struct ata_link *link,
141 unsigned int *class, unsigned long deadline)
142{
143 u8 dmactl;
144 void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
145
146 dmactl = readb(mmio + ATA_DMA_CMD);
147
148 /* Clear the start bit */
149 if (dmactl & ATA_DMA_START) {
150 dmactl &= ~ATA_DMA_START;
151 writeb(dmactl, mmio + ATA_DMA_CMD);
152 }
153
154 return ata_sff_softreset(link, class, deadline);
155}
156
157static int k2_sata_hardreset(struct ata_link *link,
158 unsigned int *class, unsigned long deadline)
159{
160 u8 dmactl;
161 void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
162
163 dmactl = readb(mmio + ATA_DMA_CMD);
164
165 /* Clear the start bit */
166 if (dmactl & ATA_DMA_START) {
167 dmactl &= ~ATA_DMA_START;
168 writeb(dmactl, mmio + ATA_DMA_CMD);
169 }
170
171 return sata_sff_hardreset(link, class, deadline);
172}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
Jeff Garzik057ace52005-10-22 14:27:05 -0400174static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175{
176 struct ata_ioports *ioaddr = &ap->ioaddr;
177 unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
178
179 if (tf->ctl != ap->last_ctl) {
Tejun Heo0d5ff562007-02-01 15:06:36 +0900180 writeb(tf->ctl, ioaddr->ctl_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 ap->last_ctl = tf->ctl;
182 ata_wait_idle(ap);
183 }
184 if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
Jeff Garzik850a9d82006-12-20 14:37:04 -0500185 writew(tf->feature | (((u16)tf->hob_feature) << 8),
Tejun Heo0d5ff562007-02-01 15:06:36 +0900186 ioaddr->feature_addr);
Jeff Garzik850a9d82006-12-20 14:37:04 -0500187 writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
Tejun Heo0d5ff562007-02-01 15:06:36 +0900188 ioaddr->nsect_addr);
Jeff Garzik850a9d82006-12-20 14:37:04 -0500189 writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
Tejun Heo0d5ff562007-02-01 15:06:36 +0900190 ioaddr->lbal_addr);
Jeff Garzik850a9d82006-12-20 14:37:04 -0500191 writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
Tejun Heo0d5ff562007-02-01 15:06:36 +0900192 ioaddr->lbam_addr);
Jeff Garzik850a9d82006-12-20 14:37:04 -0500193 writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
Tejun Heo0d5ff562007-02-01 15:06:36 +0900194 ioaddr->lbah_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 } else if (is_addr) {
Tejun Heo0d5ff562007-02-01 15:06:36 +0900196 writew(tf->feature, ioaddr->feature_addr);
197 writew(tf->nsect, ioaddr->nsect_addr);
198 writew(tf->lbal, ioaddr->lbal_addr);
199 writew(tf->lbam, ioaddr->lbam_addr);
200 writew(tf->lbah, ioaddr->lbah_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 }
202
203 if (tf->flags & ATA_TFLAG_DEVICE)
Tejun Heo0d5ff562007-02-01 15:06:36 +0900204 writeb(tf->device, ioaddr->device_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205
206 ata_wait_idle(ap);
207}
208
209
210static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
211{
212 struct ata_ioports *ioaddr = &ap->ioaddr;
Jeff Garzikac19bff2005-10-29 13:58:21 -0400213 u16 nsect, lbal, lbam, lbah, feature;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214
Jeff Garzikac19bff2005-10-29 13:58:21 -0400215 tf->command = k2_stat_check_status(ap);
Tejun Heo0d5ff562007-02-01 15:06:36 +0900216 tf->device = readw(ioaddr->device_addr);
217 feature = readw(ioaddr->error_addr);
218 nsect = readw(ioaddr->nsect_addr);
219 lbal = readw(ioaddr->lbal_addr);
220 lbam = readw(ioaddr->lbam_addr);
221 lbah = readw(ioaddr->lbah_addr);
Jeff Garzikac19bff2005-10-29 13:58:21 -0400222
223 tf->feature = feature;
224 tf->nsect = nsect;
225 tf->lbal = lbal;
226 tf->lbam = lbam;
227 tf->lbah = lbah;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 if (tf->flags & ATA_TFLAG_LBA48) {
Jeff Garzikac19bff2005-10-29 13:58:21 -0400230 tf->hob_feature = feature >> 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 tf->hob_nsect = nsect >> 8;
232 tf->hob_lbal = lbal >> 8;
233 tf->hob_lbam = lbam >> 8;
234 tf->hob_lbah = lbah >> 8;
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400235 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236}
237
238/**
239 * k2_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction (MMIO)
240 * @qc: Info associated with this ATA transaction.
241 *
242 * LOCKING:
Jeff Garzikcca39742006-08-24 03:19:22 -0400243 * spin_lock_irqsave(host lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 */
245
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400246static void k2_bmdma_setup_mmio(struct ata_queued_cmd *qc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247{
248 struct ata_port *ap = qc->ap;
249 unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
250 u8 dmactl;
Jeff Garzik59f99882007-05-28 07:07:20 -0400251 void __iomem *mmio = ap->ioaddr.bmdma_addr;
252
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 /* load PRD table addr. */
254 mb(); /* make sure PRD table writes are visible to controller */
Tejun Heof60d7012010-05-10 21:41:41 +0200255 writel(ap->bmdma_prd_dma, mmio + ATA_DMA_TABLE_OFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
257 /* specify data direction, triple-check start bit is clear */
258 dmactl = readb(mmio + ATA_DMA_CMD);
259 dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
260 if (!rw)
261 dmactl |= ATA_DMA_WR;
262 writeb(dmactl, mmio + ATA_DMA_CMD);
263
264 /* issue r/w command if this is not a ATA DMA command*/
265 if (qc->tf.protocol != ATA_PROT_DMA)
Tejun Heo5682ed32008-04-07 22:47:16 +0900266 ap->ops->sff_exec_command(ap, &qc->tf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267}
268
269/**
270 * k2_bmdma_start_mmio - Start a PCI IDE BMDMA transaction (MMIO)
271 * @qc: Info associated with this ATA transaction.
272 *
273 * LOCKING:
Jeff Garzikcca39742006-08-24 03:19:22 -0400274 * spin_lock_irqsave(host lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 */
276
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400277static void k2_bmdma_start_mmio(struct ata_queued_cmd *qc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278{
279 struct ata_port *ap = qc->ap;
Jeff Garzik59f99882007-05-28 07:07:20 -0400280 void __iomem *mmio = ap->ioaddr.bmdma_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 u8 dmactl;
282
283 /* start host DMA transaction */
284 dmactl = readb(mmio + ATA_DMA_CMD);
285 writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);
Pavel Machekec6add92008-06-23 11:01:31 +0200286 /* This works around possible data corruption.
287
288 On certain SATA controllers that can be seen when the r/w
289 command is given to the controller before the host DMA is
290 started.
291
292 On a Read command, the controller would initiate the
293 command to the drive even before it sees the DMA
294 start. When there are very fast drives connected to the
295 controller, or when the data request hits in the drive
296 cache, there is the possibility that the drive returns a
297 part or all of the requested data to the controller before
298 the DMA start is issued. In this case, the controller
299 would become confused as to what to do with the data. In
300 the worst case when all the data is returned back to the
301 controller, the controller could hang. In other cases it
302 could return partial data returning in data
303 corruption. This problem has been seen in PPC systems and
304 can also appear on an system with very fast disks, where
305 the SATA controller is sitting behind a number of bridges,
306 and hence there is significant latency between the r/w
307 command and the start command. */
308 /* issue r/w command if the access is to ATA */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 if (qc->tf.protocol == ATA_PROT_DMA)
Tejun Heo5682ed32008-04-07 22:47:16 +0900310 ap->ops->sff_exec_command(ap, &qc->tf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311}
312
Jeff Garzik8a60a072005-07-31 13:13:24 -0400313
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314static u8 k2_stat_check_status(struct ata_port *ap)
315{
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400316 return readl(ap->ioaddr.status_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317}
318
Al Viro3f025672013-03-31 12:46:43 -0400319static int k2_sata_show_info(struct seq_file *m, struct Scsi_Host *shost)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320{
321 struct ata_port *ap;
322 struct device_node *np;
Al Viro3f025672013-03-31 12:46:43 -0400323 int index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
325 /* Find the ata_port */
Jeff Garzik35bb94b2006-04-11 13:12:34 -0400326 ap = ata_shost_to_port(shost);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 if (ap == NULL)
328 return 0;
329
330 /* Find the OF node for the PCI device proper */
Jeff Garzikcca39742006-08-24 03:19:22 -0400331 np = pci_device_to_OF_node(to_pci_dev(ap->host->dev));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 if (np == NULL)
333 return 0;
334
335 /* Match it to a port node */
Jeff Garzikcca39742006-08-24 03:19:22 -0400336 index = (ap == ap->host->ports[0]) ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 for (np = np->child; np != NULL; np = np->sibling) {
Stephen Rothwell40cd3a42007-05-01 13:54:02 +1000338 const u32 *reg = of_get_property(np, "reg", NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339 if (!reg)
340 continue;
Al Viro3f025672013-03-31 12:46:43 -0400341 if (index == *reg) {
342 seq_printf(m, "devspec: %s\n", np->full_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 break;
Al Viro3f025672013-03-31 12:46:43 -0400344 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 }
Al Viro3f025672013-03-31 12:46:43 -0400346 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348
Jeff Garzik193515d2005-11-07 00:59:37 -0500349static struct scsi_host_template k2_sata_sht = {
Tejun Heo68d1d072008-03-25 12:22:49 +0900350 ATA_BMDMA_SHT(DRV_NAME),
Al Viro3f025672013-03-31 12:46:43 -0400351 .show_info = k2_sata_show_info,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352};
353
354
Tejun Heo029cfd62008-03-25 12:22:49 +0900355static struct ata_port_operations k2_sata_ops = {
356 .inherits = &ata_bmdma_port_ops,
David Milburnb03e66a2012-10-29 18:00:22 -0500357 .softreset = k2_sata_softreset,
358 .hardreset = k2_sata_hardreset,
Tejun Heo5682ed32008-04-07 22:47:16 +0900359 .sff_tf_load = k2_sata_tf_load,
360 .sff_tf_read = k2_sata_tf_read,
361 .sff_check_status = k2_stat_check_status,
Jeff Garzikc10340a2006-12-14 17:04:33 -0500362 .check_atapi_dma = k2_sata_check_atapi_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 .bmdma_setup = k2_bmdma_setup_mmio,
364 .bmdma_start = k2_bmdma_start_mmio,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 .scr_read = k2_sata_scr_read,
366 .scr_write = k2_sata_scr_write,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367};
368
Tejun Heo4447d352007-04-17 23:44:08 +0900369static const struct ata_port_info k2_port_info[] = {
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800370 /* chip_svw4 */
Tejun Heo4447d352007-04-17 23:44:08 +0900371 {
Sergei Shtylyov9cbe0562011-02-04 22:05:48 +0300372 .flags = ATA_FLAG_SATA | K2_FLAG_NO_ATAPI_DMA,
Erik Inge Bolsø14bdef92009-03-14 21:38:24 +0100373 .pio_mask = ATA_PIO4,
374 .mwdma_mask = ATA_MWDMA2,
Jeff Garzikbf6263a2007-07-09 12:16:50 -0400375 .udma_mask = ATA_UDMA6,
Tejun Heo4447d352007-04-17 23:44:08 +0900376 .port_ops = &k2_sata_ops,
377 },
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800378 /* chip_svw8 */
Tejun Heo4447d352007-04-17 23:44:08 +0900379 {
Sergei Shtylyov9cbe0562011-02-04 22:05:48 +0300380 .flags = ATA_FLAG_SATA | K2_FLAG_NO_ATAPI_DMA |
381 K2_FLAG_SATA_8_PORTS,
Erik Inge Bolsø14bdef92009-03-14 21:38:24 +0100382 .pio_mask = ATA_PIO4,
383 .mwdma_mask = ATA_MWDMA2,
Jeff Garzikbf6263a2007-07-09 12:16:50 -0400384 .udma_mask = ATA_UDMA6,
Tejun Heo4447d352007-04-17 23:44:08 +0900385 .port_ops = &k2_sata_ops,
386 },
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800387 /* chip_svw42 */
388 {
Sergei Shtylyov9cbe0562011-02-04 22:05:48 +0300389 .flags = ATA_FLAG_SATA | K2_FLAG_BAR_POS_3,
Erik Inge Bolsø14bdef92009-03-14 21:38:24 +0100390 .pio_mask = ATA_PIO4,
391 .mwdma_mask = ATA_MWDMA2,
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800392 .udma_mask = ATA_UDMA6,
393 .port_ops = &k2_sata_ops,
394 },
395 /* chip_svw43 */
396 {
Sergei Shtylyov9cbe0562011-02-04 22:05:48 +0300397 .flags = ATA_FLAG_SATA,
Erik Inge Bolsø14bdef92009-03-14 21:38:24 +0100398 .pio_mask = ATA_PIO4,
399 .mwdma_mask = ATA_MWDMA2,
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800400 .udma_mask = ATA_UDMA6,
401 .port_ops = &k2_sata_ops,
402 },
Tejun Heo4447d352007-04-17 23:44:08 +0900403};
404
Tejun Heo0d5ff562007-02-01 15:06:36 +0900405static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406{
407 port->cmd_addr = base + K2_SATA_TF_CMD_OFFSET;
408 port->data_addr = base + K2_SATA_TF_DATA_OFFSET;
409 port->feature_addr =
410 port->error_addr = base + K2_SATA_TF_ERROR_OFFSET;
411 port->nsect_addr = base + K2_SATA_TF_NSECT_OFFSET;
412 port->lbal_addr = base + K2_SATA_TF_LBAL_OFFSET;
413 port->lbam_addr = base + K2_SATA_TF_LBAM_OFFSET;
414 port->lbah_addr = base + K2_SATA_TF_LBAH_OFFSET;
415 port->device_addr = base + K2_SATA_TF_DEVICE_OFFSET;
416 port->command_addr =
417 port->status_addr = base + K2_SATA_TF_CMDSTAT_OFFSET;
418 port->altstatus_addr =
419 port->ctl_addr = base + K2_SATA_TF_CTL_OFFSET;
420 port->bmdma_addr = base + K2_SATA_DMA_CMD_OFFSET;
421 port->scr_addr = base + K2_SATA_SCR_STATUS_OFFSET;
422}
423
424
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400425static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426{
Tejun Heo4447d352007-04-17 23:44:08 +0900427 const struct ata_port_info *ppi[] =
428 { &k2_port_info[ent->driver_data], NULL };
429 struct ata_host *host;
Jeff Garzikea6ba102005-08-30 05:18:18 -0400430 void __iomem *mmio_base;
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800431 int n_ports, i, rc, bar_pos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
Joe Perches06296a12011-04-15 15:52:00 -0700433 ata_print_version_once(&pdev->dev, DRV_VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
Tejun Heo4447d352007-04-17 23:44:08 +0900435 /* allocate host */
436 n_ports = 4;
437 if (ppi[0]->flags & K2_FLAG_SATA_8_PORTS)
438 n_ports = 8;
439
440 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
441 if (!host)
442 return -ENOMEM;
443
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800444 bar_pos = 5;
445 if (ppi[0]->flags & K2_FLAG_BAR_POS_3)
446 bar_pos = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 /*
448 * If this driver happens to only be useful on Apple's K2, then
449 * we should check that here as it has a normal Serverworks ID
450 */
Tejun Heo24dc5f32007-01-20 16:00:28 +0900451 rc = pcim_enable_device(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 if (rc)
453 return rc;
Tejun Heo4447d352007-04-17 23:44:08 +0900454
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 /*
456 * Check if we have resources mapped at all (second function may
457 * have been disabled by firmware)
458 */
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800459 if (pci_resource_len(pdev, bar_pos) == 0) {
460 /* In IDE mode we need to pin the device to ensure that
461 pcim_release does not clear the busmaster bit in config
462 space, clearing causes busmaster DMA to fail on
463 ports 3 & 4 */
464 pcim_pin_device(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 return -ENODEV;
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800466 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467
Tejun Heo0d5ff562007-02-01 15:06:36 +0900468 /* Request and iomap PCI regions */
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800469 rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME);
Tejun Heo0d5ff562007-02-01 15:06:36 +0900470 if (rc == -EBUSY)
Tejun Heo24dc5f32007-01-20 16:00:28 +0900471 pcim_pin_device(pdev);
Tejun Heo0d5ff562007-02-01 15:06:36 +0900472 if (rc)
Tejun Heo24dc5f32007-01-20 16:00:28 +0900473 return rc;
Tejun Heo4447d352007-04-17 23:44:08 +0900474 host->iomap = pcim_iomap_table(pdev);
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800475 mmio_base = host->iomap[bar_pos];
Tejun Heo4447d352007-04-17 23:44:08 +0900476
477 /* different controllers have different number of ports - currently 4 or 8 */
478 /* All ports are on the same function. Multi-function device is no
479 * longer available. This should not be seen in any system. */
Tejun Heocbcdd872007-08-18 13:14:55 +0900480 for (i = 0; i < host->n_ports; i++) {
481 struct ata_port *ap = host->ports[i];
482 unsigned int offset = i * K2_SATA_PORT_OFFSET;
483
484 k2_sata_setup_port(&ap->ioaddr, mmio_base + offset);
485
486 ata_port_pbar_desc(ap, 5, -1, "mmio");
487 ata_port_pbar_desc(ap, 5, offset, "port");
488 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
Quentin Lambertc54c7192015-04-08 14:34:10 +0200490 rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 if (rc)
Tejun Heo24dc5f32007-01-20 16:00:28 +0900492 return rc;
Quentin Lambertc54c7192015-04-08 14:34:10 +0200493 rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 if (rc)
Tejun Heo24dc5f32007-01-20 16:00:28 +0900495 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 /* Clear a magic bit in SCR1 according to Darwin, those help
498 * some funky seagate drives (though so far, those were already
Rolf Eike Beer104e5012005-03-27 08:50:38 -0500499 * set by the firmware on the machines I had access to)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 */
501 writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
502 mmio_base + K2_SATA_SICR1_OFFSET);
503
504 /* Clear SATA error & interrupts we don't use */
505 writel(0xffffffff, mmio_base + K2_SATA_SCR_ERROR_OFFSET);
506 writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
507
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 pci_set_master(pdev);
Tejun Heoc3b28892010-05-19 22:10:21 +0200509 return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
Tejun Heo9363c382008-04-07 22:47:16 +0900510 IRQF_SHARED, &k2_sata_sht);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511}
512
Narendra Sankar60bf09a2005-05-25 16:51:00 -0700513/* 0x240 is device ID for Apple K2 device
514 * 0x241 is device ID for Serverworks Frodo4
515 * 0x242 is device ID for Serverworks Frodo8
516 * 0x24a is device ID for BCM5785 (aka HT1000) HT southbridge integrated SATA
517 * controller
518 * */
Jeff Garzik3b7d6972005-11-10 11:04:11 -0500519static const struct pci_device_id k2_sata_pci_tbl[] = {
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800520 { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 },
Jeff Garzikaeb74912008-04-12 00:11:35 -0400521 { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw8 },
522 { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw4 },
Anantha Subramanyam931506d2008-02-28 15:58:35 -0800523 { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 },
524 { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 },
525 { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 },
526 { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 },
Jeff Garzik2d2744f2006-09-28 20:21:59 -0400527
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 { }
529};
530
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531static struct pci_driver k2_sata_pci_driver = {
532 .name = DRV_NAME,
533 .id_table = k2_sata_pci_tbl,
534 .probe = k2_sata_init_one,
535 .remove = ata_pci_remove_one,
536};
537
Axel Lin2fc75da2012-04-19 13:43:05 +0800538module_pci_driver(k2_sata_pci_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540MODULE_AUTHOR("Benjamin Herrenschmidt");
541MODULE_DESCRIPTION("low-level driver for K2 SATA controller");
542MODULE_LICENSE("GPL");
543MODULE_DEVICE_TABLE(pci, k2_sata_pci_tbl);
544MODULE_VERSION(DRV_VERSION);