Blame view

drivers/ata/pata_atiixp.c 8.67 KB
09c434b8a   Thomas Gleixner   treewide: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0-only
669a5db41   Jeff Garzik   [libata] Add a bu...
2
3
4
  /*
   * pata_atiixp.c 	- ATI PATA for new ATA layer
   *			  (C) 2005 Red Hat Inc
e99846f18   Bartlomiej Zolnierkiewicz   [libata] pata_ati...
5
   *			  (C) 2009-2010 Bartlomiej Zolnierkiewicz
669a5db41   Jeff Garzik   [libata] Add a bu...
6
7
8
9
10
11
12
13
14
15
16
17
18
   *
   * 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>
669a5db41   Jeff Garzik   [libata] Add a bu...
19
20
21
22
  #include <linux/blkdev.h>
  #include <linux/delay.h>
  #include <scsi/scsi_host.h>
  #include <linux/libata.h>
1117c811a   Arnd Hannemann   pata_atiixp: over...
23
  #include <linux/dmi.h>
669a5db41   Jeff Garzik   [libata] Add a bu...
24
25
  
  #define DRV_NAME "pata_atiixp"
2a3103ce4   Jeff Garzik   [libata] Bump dri...
26
  #define DRV_VERSION "0.4.6"
669a5db41   Jeff Garzik   [libata] Add a bu...
27
28
29
30
31
32
33
34
35
  
  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
  };
1117c811a   Arnd Hannemann   pata_atiixp: over...
36
37
38
39
40
41
42
43
44
45
46
  static const struct dmi_system_id attixp_cable_override_dmi_table[] = {
  	{
  		/* Board has onboard PATA<->SATA converters */
  		.ident = "MSI E350DM-E33",
  		.matches = {
  			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
  			DMI_MATCH(DMI_BOARD_NAME, "E350DM-E33(MS-7720)"),
  		},
  	},
  	{ }
  };
847086069   Alan Cox   pata_atiixp: supp...
47
48
49
50
  static int atiixp_cable_detect(struct ata_port *ap)
  {
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	u8 udma;
1117c811a   Arnd Hannemann   pata_atiixp: over...
51
52
  	if (dmi_check_system(attixp_cable_override_dmi_table))
  		return ATA_CBL_PATA40_SHORT;
847086069   Alan Cox   pata_atiixp: supp...
53
54
55
56
57
58
59
  	/* 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...
60
  static DEFINE_SPINLOCK(atiixp_lock);
669a5db41   Jeff Garzik   [libata] Add a bu...
61
  /**
46b9e7707   Bartlomiej Zolnierkiewicz   pata_atiixp: add ...
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
   *	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...
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
   *	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...
102
  	int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
103
104
  	u32 pio_timing_data;
  	u16 pio_mode_data;
669a5db41   Jeff Garzik   [libata] Add a bu...
105
106
107
108
109
  
  	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 ...
110
  	pci_read_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
d7b5a23fc   Jeff Garzik   [libata] pata_ati...
111
112
  	pio_timing_data &= ~(0xFF << timing_shift);
  	pio_timing_data |= (pio_timings[pio] << timing_shift);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
113
  	pci_write_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
669a5db41   Jeff Garzik   [libata] Add a bu...
114
115
116
117
118
119
120
121
122
123
124
125
126
  }
  
  /**
   *	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...
127
128
  	unsigned long flags;
  	spin_lock_irqsave(&atiixp_lock, flags);
669a5db41   Jeff Garzik   [libata] Add a bu...
129
  	atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0);
e99846f18   Bartlomiej Zolnierkiewicz   [libata] pata_ati...
130
  	spin_unlock_irqrestore(&atiixp_lock, flags);
669a5db41   Jeff Garzik   [libata] Add a bu...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  }
  
  /**
   *	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...
150
151
152
  	unsigned long flags;
  
  	spin_lock_irqsave(&atiixp_lock, flags);
669a5db41   Jeff Garzik   [libata] Add a bu...
153
154
155
156
157
158
159
160
161
162
163
  
  	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...
164
  		int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
165
  		u32 mwdma_timing_data;
669a5db41   Jeff Garzik   [libata] Add a bu...
166
167
  
  		dma -= XFER_MW_DMA_0;
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
168
169
  		pci_read_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
  				      &mwdma_timing_data);
669a5db41   Jeff Garzik   [libata] Add a bu...
170
171
  		mwdma_timing_data &= ~(0xFF << timing_shift);
  		mwdma_timing_data |= (mwdma_timings[dma] << timing_shift);
1fd4bbec8   Bartlomiej Zolnierkiewicz   pata_atiixp: fix ...
172
173
  		pci_write_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
  				       mwdma_timing_data);
669a5db41   Jeff Garzik   [libata] Add a bu...
174
175
176
177
178
  	}
  	/*
  	 *	We must now look at the PIO mode situation. We may need to
  	 *	adjust the PIO mode to keep the timings acceptable
  	 */
273b542e7   Colin Ian King   pata_atiixp: fix ...
179
180
  	if (adev->dma_mode >= XFER_MW_DMA_2)
  		wanted_pio = 4;
669a5db41   Jeff Garzik   [libata] Add a bu...
181
182
183
184
185
186
187
188
  	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...
189
  	spin_unlock_irqrestore(&atiixp_lock, flags);
669a5db41   Jeff Garzik   [libata] Add a bu...
190
191
192
193
194
195
196
197
  }
  
  /**
   *	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...
198
199
200
   *
   *	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...
201
202
203
204
205
206
207
208
209
210
211
212
   */
  
  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...
213
  	if (ata_using_udma(adev))
669a5db41   Jeff Garzik   [libata] Add a bu...
214
215
216
217
218
219
220
221
222
223
224
225
226
  		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...
227
228
229
   *
   *	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...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
   */
  
  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...
246
  	ATA_BMDMA_SHT(DRV_NAME),
635adc280   Alan Cox   pata_atiixp: Use ...
247
  	.sg_tablesize		= LIBATA_DUMB_MAX_PRD,
669a5db41   Jeff Garzik   [libata] Add a bu...
248
249
250
  };
  
  static struct ata_port_operations atiixp_port_ops = {
029cfd6b7   Tejun Heo   libata: implement...
251
  	.inherits	= &ata_bmdma_port_ops,
669a5db41   Jeff Garzik   [libata] Add a bu...
252

f47451c45   Tejun Heo   libata-sff: ata_s...
253
  	.qc_prep 	= ata_bmdma_dumb_qc_prep,
669a5db41   Jeff Garzik   [libata] Add a bu...
254
255
  	.bmdma_start 	= atiixp_bmdma_start,
  	.bmdma_stop	= atiixp_bmdma_stop,
bda302881   Jeff Garzik   [libata] Don't us...
256

46b9e7707   Bartlomiej Zolnierkiewicz   pata_atiixp: add ...
257
  	.prereset	= atiixp_prereset,
029cfd6b7   Tejun Heo   libata: implement...
258
259
260
  	.cable_detect	= atiixp_cable_detect,
  	.set_piomode	= atiixp_set_piomode,
  	.set_dmamode	= atiixp_set_dmamode,
669a5db41   Jeff Garzik   [libata] Add a bu...
261
  };
16028232b   Tejun Heo   pata_atiixp: upda...
262
  static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
669a5db41   Jeff Garzik   [libata] Add a bu...
263
  {
1626aeb88   Tejun Heo   libata: clean up ...
264
  	static const struct ata_port_info info = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
265
  		.flags = ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
266
267
268
  		.pio_mask = ATA_PIO4,
  		.mwdma_mask = ATA_MWDMA12_ONLY,
  		.udma_mask = ATA_UDMA5,
669a5db41   Jeff Garzik   [libata] Add a bu...
269
270
  		.port_ops = &atiixp_port_ops
  	};
16028232b   Tejun Heo   pata_atiixp: upda...
271
  	const struct ata_port_info *ppi[] = { &info, &info };
16028232b   Tejun Heo   pata_atiixp: upda...
272

e47ecd4e4   Darren Stevens   libata:pata_atiix...
273
  	/* SB600 doesn't have secondary port wired */
ce42c1768   Nathan Chancellor   pata_atiixp: Remo...
274
  	if (pdev->device == PCI_DEVICE_ID_ATI_IXP600_IDE)
e47ecd4e4   Darren Stevens   libata:pata_atiix...
275
  		ppi[1] = &ata_dummy_port_info;
1c5afdf7a   Tejun Heo   libata-sff: separ...
276
277
  	return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL,
  				      ATA_HOST_PARALLEL_SCAN);
669a5db41   Jeff Garzik   [libata] Add a bu...
278
  }
2d2744fc8   Jeff Garzik   [libata] PCI ID t...
279
280
281
282
283
  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...
284
  	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
5deab5366   Shane Huang   ahci / atiixp / p...
285
  	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), },
2d2744fc8   Jeff Garzik   [libata] PCI ID t...
286
287
  
  	{ },
669a5db41   Jeff Garzik   [libata] Add a bu...
288
289
290
291
292
293
  };
  
  static struct pci_driver atiixp_pci_driver = {
  	.name 		= DRV_NAME,
  	.id_table	= atiixp,
  	.probe 		= atiixp_init_one,
30ced0f0d   Alan Cox   [PATCH] PATA liba...
294
  	.remove		= ata_pci_remove_one,
58eb8cd56   Bartlomiej Zolnierkiewicz   ata: use CONFIG_P...
295
  #ifdef CONFIG_PM_SLEEP
30ced0f0d   Alan Cox   [PATCH] PATA liba...
296
297
  	.resume		= ata_pci_device_resume,
  	.suspend	= ata_pci_device_suspend,
438ac6d5e   Tejun Heo   libata: add missi...
298
  #endif
669a5db41   Jeff Garzik   [libata] Add a bu...
299
  };
2fc75da0c   Axel Lin   ata: use module_p...
300
  module_pci_driver(atiixp_pci_driver);
669a5db41   Jeff Garzik   [libata] Add a bu...
301

669a5db41   Jeff Garzik   [libata] Add a bu...
302
303
304
305
306
  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);