Blame view

drivers/ata/pata_atiixp.c 8.33 KB
669a5db41   Jeff Garzik   [libata] Add a bu...
1
2
3
  /*
   * pata_atiixp.c 	- ATI PATA for new ATA layer
   *			  (C) 2005 Red Hat Inc
e99846f18   Bartlomiej Zolnierkiewicz   [libata] pata_ati...
4
   *			  (C) 2009-2010 Bartlomiej Zolnierkiewicz
669a5db41   Jeff Garzik   [libata] Add a bu...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   *
   * Based on
   *
   *  linux/drivers/ide/pci/atiixp.c	Version 0.01-bart2	Feb. 26, 2004
   *
   *  Copyright (C) 2003 ATI Inc. <hyu@ati.com>
   *  Copyright (C) 2004 Bartlomiej Zolnierkiewicz
   *
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/pci.h>
  #include <linux/init.h>
  #include <linux/blkdev.h>
  #include <linux/delay.h>
  #include <scsi/scsi_host.h>
  #include <linux/libata.h>
  
  #define DRV_NAME "pata_atiixp"
2a3103ce4   Jeff Garzik   [libata] Bump dri...
25
  #define DRV_VERSION "0.4.6"
669a5db41   Jeff Garzik   [libata] Add a bu...
26
27
28
29
30
31
32
33
34
  
  enum {
  	ATIIXP_IDE_PIO_TIMING	= 0x40,
  	ATIIXP_IDE_MWDMA_TIMING	= 0x44,
  	ATIIXP_IDE_PIO_CONTROL	= 0x48,
  	ATIIXP_IDE_PIO_MODE	= 0x4a,
  	ATIIXP_IDE_UDMA_CONTROL	= 0x54,
  	ATIIXP_IDE_UDMA_MODE 	= 0x56
  };
847086069   Alan Cox   pata_atiixp: supp...
35
36
37
38
39
40
41
42
43
44
45
46
  static int atiixp_cable_detect(struct ata_port *ap)
  {
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	u8 udma;
  
  	/* Hack from drivers/ide/pci. Really we want to know how to do the
  	   raw detection not play follow the bios mode guess */
  	pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
  	if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40)
  		return  ATA_CBL_PATA80;
  	return ATA_CBL_PATA40;
  }
e99846f18   Bartlomiej Zolnierkiewicz   [libata] pata_ati...
47
  static DEFINE_SPINLOCK(atiixp_lock);
669a5db41   Jeff Garzik   [libata] Add a bu...
48
  /**
46b9e7707   Bartlomiej Zolnierkiewicz   pata_atiixp: add ...
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
   *	atiixp_prereset	-	perform reset handling
   *	@link: ATA link
   *	@deadline: deadline jiffies for the operation
   *
   *	Reset sequence checking enable bits to see which ports are
   *	active.
   */
  
  static int atiixp_prereset(struct ata_link *link, unsigned long deadline)
  {
  	static const struct pci_bits atiixp_enable_bits[] = {
  		{ 0x48, 1, 0x01, 0x00 },
  		{ 0x48, 1, 0x08, 0x00 }
  	};
  
  	struct ata_port *ap = link->ap;
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  
  	if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
  		return -ENOENT;
  
  	return ata_sff_prereset(link, deadline);
  }
  
  /**
669a5db41   Jeff Garzik   [libata] Add a bu...
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
   *	atiixp_set_pio_timing	-	set initial PIO mode data
   *	@ap: ATA interface
   *	@adev: ATA device
   *
   *	Called by both the pio and dma setup functions to set the controller
   *	timings for PIO transfers. We must load both the mode number and
   *	timing values into the controller.
   */
  
  static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio)
  {
  	static u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 };
  
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	int dn = 2 * ap->port_no + adev->devno;
669a5db41   Jeff Garzik   [libata] Add a bu...
89
  	int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
90
91
  	u32 pio_timing_data;
  	u16 pio_mode_data;
669a5db41   Jeff Garzik   [libata] Add a bu...
92
93
94
95
96
  
  	pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
  	pio_mode_data &= ~(0x7 << (4 * dn));
  	pio_mode_data |= pio << (4 * dn);
  	pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
97
  	pci_read_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
d7b5a23fc   Jeff Garzik   [libata] pata_ati...
98
99
  	pio_timing_data &= ~(0xFF << timing_shift);
  	pio_timing_data |= (pio_timings[pio] << timing_shift);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
100
  	pci_write_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
669a5db41   Jeff Garzik   [libata] Add a bu...
101
102
103
104
105
106
107
108
109
110
111
112
113
  }
  
  /**
   *	atiixp_set_piomode	-	set initial PIO mode data
   *	@ap: ATA interface
   *	@adev: ATA device
   *
   *	Called to do the PIO mode setup. We use a shared helper for this
   *	as the DMA setup must also adjust the PIO timing information.
   */
  
  static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev)
  {
e99846f18   Bartlomiej Zolnierkiewicz   [libata] pata_ati...
114
115
  	unsigned long flags;
  	spin_lock_irqsave(&atiixp_lock, flags);
669a5db41   Jeff Garzik   [libata] Add a bu...
116
  	atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0);
e99846f18   Bartlomiej Zolnierkiewicz   [libata] pata_ati...
117
  	spin_unlock_irqrestore(&atiixp_lock, flags);
669a5db41   Jeff Garzik   [libata] Add a bu...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  }
  
  /**
   *	atiixp_set_dmamode	-	set initial DMA mode data
   *	@ap: ATA interface
   *	@adev: ATA device
   *
   *	Called to do the DMA mode setup. We use timing tables for most
   *	modes but must tune an appropriate PIO mode to match.
   */
  
  static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  {
  	static u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 };
  
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	int dma = adev->dma_mode;
  	int dn = 2 * ap->port_no + adev->devno;
  	int wanted_pio;
e99846f18   Bartlomiej Zolnierkiewicz   [libata] pata_ati...
137
138
139
  	unsigned long flags;
  
  	spin_lock_irqsave(&atiixp_lock, flags);
669a5db41   Jeff Garzik   [libata] Add a bu...
140
141
142
143
144
145
146
147
148
149
150
  
  	if (adev->dma_mode >= XFER_UDMA_0) {
  		u16 udma_mode_data;
  
  		dma -= XFER_UDMA_0;
  
  		pci_read_config_word(pdev, ATIIXP_IDE_UDMA_MODE, &udma_mode_data);
  		udma_mode_data &= ~(0x7 << (4 * dn));
  		udma_mode_data |= dma << (4 * dn);
  		pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data);
  	} else {
669a5db41   Jeff Garzik   [libata] Add a bu...
151
  		int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
152
  		u32 mwdma_timing_data;
669a5db41   Jeff Garzik   [libata] Add a bu...
153
154
  
  		dma -= XFER_MW_DMA_0;
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
155
156
  		pci_read_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
  				      &mwdma_timing_data);
669a5db41   Jeff Garzik   [libata] Add a bu...
157
158
  		mwdma_timing_data &= ~(0xFF << timing_shift);
  		mwdma_timing_data |= (mwdma_timings[dma] << timing_shift);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
159
160
  		pci_write_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
  				       mwdma_timing_data);
669a5db41   Jeff Garzik   [libata] Add a bu...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  	}
  	/*
  	 *	We must now look at the PIO mode situation. We may need to
  	 *	adjust the PIO mode to keep the timings acceptable
  	 */
  	 if (adev->dma_mode >= XFER_MW_DMA_2)
  	 	wanted_pio = 4;
  	else if (adev->dma_mode == XFER_MW_DMA_1)
  		wanted_pio = 3;
  	else if (adev->dma_mode == XFER_MW_DMA_0)
  		wanted_pio = 0;
  	else BUG();
  
  	if (adev->pio_mode != wanted_pio)
  		atiixp_set_pio_timing(ap, adev, wanted_pio);
e99846f18   Bartlomiej Zolnierkiewicz   [libata] pata_ati...
176
  	spin_unlock_irqrestore(&atiixp_lock, flags);
669a5db41   Jeff Garzik   [libata] Add a bu...
177
178
179
180
181
182
183
184
  }
  
  /**
   *	atiixp_bmdma_start	-	DMA start callback
   *	@qc: Command in progress
   *
   *	When DMA begins we need to ensure that the UDMA control
   *	register for the channel is correctly set.
21d2c925d   Alan Cox   pata_atiixp: Audi...
185
186
187
   *
   *	Note: The host lock held by the libata layer protects
   *	us from two channels both trying to set DMA bits at once
669a5db41   Jeff Garzik   [libata] Add a bu...
188
189
190
191
192
193
194
195
196
197
198
199
   */
  
  static void atiixp_bmdma_start(struct ata_queued_cmd *qc)
  {
  	struct ata_port *ap = qc->ap;
  	struct ata_device *adev = qc->dev;
  
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	int dn = (2 * ap->port_no) + adev->devno;
  	u16 tmp16;
  
  	pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
b15b3ebae   Alan Cox   libata: Fix a lar...
200
  	if (ata_using_udma(adev))
669a5db41   Jeff Garzik   [libata] Add a bu...
201
202
203
204
205
206
207
208
209
210
211
212
213
  		tmp16 |= (1 << dn);
  	else
  		tmp16 &= ~(1 << dn);
  	pci_write_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
  	ata_bmdma_start(qc);
  }
  
  /**
   *	atiixp_dma_stop	-	DMA stop callback
   *	@qc: Command in progress
   *
   *	DMA has completed. Clear the UDMA flag as the next operations will
   *	be PIO ones not UDMA data transfer.
21d2c925d   Alan Cox   pata_atiixp: Audi...
214
215
216
   *
   *	Note: The host lock held by the libata layer protects
   *	us from two channels both trying to set DMA bits at once
669a5db41   Jeff Garzik   [libata] Add a bu...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
   */
  
  static void atiixp_bmdma_stop(struct ata_queued_cmd *qc)
  {
  	struct ata_port *ap = qc->ap;
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	int dn = (2 * ap->port_no) + qc->dev->devno;
  	u16 tmp16;
  
  	pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
  	tmp16 &= ~(1 << dn);
  	pci_write_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
  	ata_bmdma_stop(qc);
  }
  
  static struct scsi_host_template atiixp_sht = {
68d1d07b5   Tejun Heo   libata: implement...
233
  	ATA_BMDMA_SHT(DRV_NAME),
635adc280   Alan Cox   pata_atiixp: Use ...
234
  	.sg_tablesize		= LIBATA_DUMB_MAX_PRD,
669a5db41   Jeff Garzik   [libata] Add a bu...
235
236
237
  };
  
  static struct ata_port_operations atiixp_port_ops = {
029cfd6b7   Tejun Heo   libata: implement...
238
  	.inherits	= &ata_bmdma_port_ops,
669a5db41   Jeff Garzik   [libata] Add a bu...
239

f47451c45   Tejun Heo   libata-sff: ata_s...
240
  	.qc_prep 	= ata_bmdma_dumb_qc_prep,
669a5db41   Jeff Garzik   [libata] Add a bu...
241
242
  	.bmdma_start 	= atiixp_bmdma_start,
  	.bmdma_stop	= atiixp_bmdma_stop,
bda302881   Jeff Garzik   [libata] Don't us...
243

46b9e7707   Bartlomiej Zolnierkiewicz   pata_atiixp: add ...
244
  	.prereset	= atiixp_prereset,
029cfd6b7   Tejun Heo   libata: implement...
245
246
247
  	.cable_detect	= atiixp_cable_detect,
  	.set_piomode	= atiixp_set_piomode,
  	.set_dmamode	= atiixp_set_dmamode,
669a5db41   Jeff Garzik   [libata] Add a bu...
248
  };
16028232b   Tejun Heo   pata_atiixp: upda...
249
  static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
669a5db41   Jeff Garzik   [libata] Add a bu...
250
  {
1626aeb88   Tejun Heo   libata: clean up ...
251
  	static const struct ata_port_info info = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
252
  		.flags = ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
253
254
255
  		.pio_mask = ATA_PIO4,
  		.mwdma_mask = ATA_MWDMA12_ONLY,
  		.udma_mask = ATA_UDMA5,
669a5db41   Jeff Garzik   [libata] Add a bu...
256
257
  		.port_ops = &atiixp_port_ops
  	};
16028232b   Tejun Heo   pata_atiixp: upda...
258
  	const struct ata_port_info *ppi[] = { &info, &info };
16028232b   Tejun Heo   pata_atiixp: upda...
259

1c5afdf7a   Tejun Heo   libata-sff: separ...
260
261
  	return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL,
  				      ATA_HOST_PARALLEL_SCAN);
669a5db41   Jeff Garzik   [libata] Add a bu...
262
  }
2d2744fc8   Jeff Garzik   [libata] PCI ID t...
263
264
265
266
267
  static const struct pci_device_id atiixp[] = {
  	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), },
  	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
  	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
  	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
1ca972c20   Jeff Garzik   [libata] pata_ati...
268
  	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
5deab5366   Shane Huang   ahci / atiixp / p...
269
  	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), },
2d2744fc8   Jeff Garzik   [libata] PCI ID t...
270
271
  
  	{ },
669a5db41   Jeff Garzik   [libata] Add a bu...
272
273
274
275
276
277
  };
  
  static struct pci_driver atiixp_pci_driver = {
  	.name 		= DRV_NAME,
  	.id_table	= atiixp,
  	.probe 		= atiixp_init_one,
30ced0f0d   Alan Cox   [PATCH] PATA liba...
278
  	.remove		= ata_pci_remove_one,
438ac6d5e   Tejun Heo   libata: add missi...
279
  #ifdef CONFIG_PM
30ced0f0d   Alan Cox   [PATCH] PATA liba...
280
281
  	.resume		= ata_pci_device_resume,
  	.suspend	= ata_pci_device_suspend,
438ac6d5e   Tejun Heo   libata: add missi...
282
  #endif
669a5db41   Jeff Garzik   [libata] Add a bu...
283
284
285
286
287
288
289
290
291
292
293
294
  };
  
  static int __init atiixp_init(void)
  {
  	return pci_register_driver(&atiixp_pci_driver);
  }
  
  
  static void __exit atiixp_exit(void)
  {
  	pci_unregister_driver(&atiixp_pci_driver);
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
295
296
297
298
299
300
301
302
  MODULE_AUTHOR("Alan Cox");
  MODULE_DESCRIPTION("low-level driver for ATI IXP200/300/400");
  MODULE_LICENSE("GPL");
  MODULE_DEVICE_TABLE(pci, atiixp);
  MODULE_VERSION(DRV_VERSION);
  
  module_init(atiixp_init);
  module_exit(atiixp_exit);