Blame view

drivers/ata/pata_at32.c 10.3 KB
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  /*
   * AVR32 SMC/CFC PATA Driver
   *
   * Copyright (C) 2007 Atmel Norway
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License version
   * 2 as published by the Free Software Foundation.
   */
  
  #define DEBUG
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/device.h>
  #include <linux/platform_device.h>
  #include <linux/delay.h>
  #include <linux/interrupt.h>
  #include <linux/irq.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
21
  #include <linux/slab.h>
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
22
23
24
25
26
  #include <scsi/scsi_host.h>
  #include <linux/ata.h>
  #include <linux/libata.h>
  #include <linux/err.h>
  #include <linux/io.h>
3663b736a   Haavard Skinnemoen   avr32: Use <mach/...
27
28
  #include <mach/board.h>
  #include <mach/smc.h>
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
29
30
  
  #define DRV_NAME "pata_at32"
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
31
  #define DRV_VERSION "0.0.3"
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  
  /*
   * CompactFlash controller memory layout relative to the base address:
   *
   *	Attribute memory:  0000 0000 -> 003f ffff
   *	Common memory:	   0040 0000 -> 007f ffff
   *	I/O memory:	   0080 0000 -> 00bf ffff
   *	True IDE Mode:	   00c0 0000 -> 00df ffff
   *	Alt IDE Mode:	   00e0 0000 -> 00ff ffff
   *
   * Only True IDE and Alt True IDE mode are needed for this driver.
   *
   *	True IDE mode	  => CS0 = 0, CS1 = 1 (cmd, error, stat, etc)
   *	Alt True IDE mode => CS0 = 1, CS1 = 0 (ctl, alt_stat)
   */
  #define CF_IDE_OFFSET	  0x00c00000
  #define CF_ALT_IDE_OFFSET 0x00e00000
  #define CF_RES_SIZE	  2048
  
  /*
   * Define DEBUG_BUS if you are doing debugging of your own EBI -> PATA
   * adaptor with a logic analyzer or similar.
   */
  #undef DEBUG_BUS
  
  /*
   * ATA PIO modes
   *
   *	Name	| Mb/s	| Min cycle time | Mask
   *	--------+-------+----------------+--------
   *	Mode 0	| 3.3	| 600 ns	 | 0x01
   *	Mode 1	| 5.2	| 383 ns	 | 0x03
   *	Mode 2	| 8.3	| 240 ns	 | 0x07
   *	Mode 3	| 11.1	| 180 ns	 | 0x0f
   *	Mode 4	| 16.7	| 120 ns	 | 0x1f
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
67
68
   *
   * Alter PIO_MASK below according to table to set maximal PIO mode.
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
69
   */
14bdef982   Erik Inge Bolsø   [libata] convert ...
70
71
72
  enum {
    PIO_MASK = ATA_PIO4,
  };
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  
  /*
   * Struct containing private information about device.
   */
  struct at32_ide_info {
  	unsigned int		irq;
  	struct resource		res_ide;
  	struct resource		res_alt;
  	void __iomem		*ide_addr;
  	void __iomem		*alt_addr;
  	unsigned int		cs;
  	struct smc_config	smc;
  };
  
  /*
   * Setup SMC for the given ATA timing.
   */
  static int pata_at32_setup_timing(struct device *dev,
  				  struct at32_ide_info *info,
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
92
  				  const struct ata_timing *ata)
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
93
  {
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
94
  	struct smc_config *smc = &info->smc;
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
95
  	struct smc_timing timing;
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
96
97
98
  
  	int active;
  	int recover;
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
99
  	memset(&timing, 0, sizeof(struct smc_timing));
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
100
  	/* Total cycle time */
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
101
  	timing.read_cycle  = ata->cyc8b;
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
102
103
  
  	/* DIOR <= CFIOR timings */
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
104
105
106
107
108
109
  	timing.nrd_setup   = ata->setup;
  	timing.nrd_pulse   = ata->act8b;
  	timing.nrd_recover = ata->rec8b;
  
  	/* Convert nanosecond timing to clock cycles */
  	smc_set_timing(smc, &timing);
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
110

1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
111
112
113
114
  	/* Add one extra cycle setup due to signal ring */
  	smc->nrd_setup = smc->nrd_setup + 1;
  
  	active  = smc->nrd_setup + smc->nrd_pulse;
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
115
  	recover = smc->read_cycle - active;
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
116
117
118
  	/* Need at least two cycles recovery */
  	if (recover < 2)
  	  smc->read_cycle = active + 2;
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
119
120
  
  	/* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
121
122
  	smc->ncs_read_setup = 1;
  	smc->ncs_read_pulse = smc->read_cycle - 2;
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
123
124
125
126
127
128
129
  
  	/* Write timings same as read timings */
  	smc->write_cycle = smc->read_cycle;
  	smc->nwe_setup = smc->nrd_setup;
  	smc->nwe_pulse = smc->nrd_pulse;
  	smc->ncs_write_setup = smc->ncs_read_setup;
  	smc->ncs_write_pulse = smc->ncs_read_pulse;
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
130
131
132
133
134
135
136
  	/* Do some debugging output of ATA and SMC timings */
  	dev_dbg(dev, "ATA: C=%d S=%d P=%d R=%d
  ",
  		ata->cyc8b, ata->setup, ata->act8b, ata->rec8b);
  
  	dev_dbg(dev, "SMC: C=%d S=%d P=%d NS=%d NP=%d
  ",
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
137
  		smc->read_cycle, smc->nrd_setup, smc->nrd_pulse,
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
138
  		smc->ncs_read_setup, smc->ncs_read_pulse);
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  
  	/* Finally, configure the SMC */
  	return smc_set_configuration(info->cs, smc);
  }
  
  /*
   * Procedures for libATA.
   */
  static void pata_at32_set_piomode(struct ata_port *ap, struct ata_device *adev)
  {
  	struct ata_timing timing;
  	struct at32_ide_info *info = ap->host->private_data;
  
  	int ret;
  
  	/* Compute ATA timing */
  	ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0);
  	if (ret) {
  		dev_warn(ap->dev, "Failed to compute ATA timing %d
  ", ret);
  		return;
  	}
  
  	/* Setup SMC to ATA timing */
  	ret = pata_at32_setup_timing(ap->dev, info, &timing);
  	if (ret) {
  		dev_warn(ap->dev, "Failed to setup ATA timing %d
  ", ret);
  		return;
  	}
  }
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
170
  static struct scsi_host_template at32_sht = {
68d1d07b5   Tejun Heo   libata: implement...
171
  	ATA_PIO_SHT(DRV_NAME),
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
172
173
174
  };
  
  static struct ata_port_operations at32_port_ops = {
029cfd6b7   Tejun Heo   libata: implement...
175
  	.inherits		= &ata_sff_port_ops,
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
176
  	.cable_detect		= ata_cable_40wire,
029cfd6b7   Tejun Heo   libata: implement...
177
  	.set_piomode		= pata_at32_set_piomode,
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
  };
  
  static int __init pata_at32_init_one(struct device *dev,
  				     struct at32_ide_info *info)
  {
  	struct ata_host *host;
  	struct ata_port *ap;
  
  	host = ata_host_alloc(dev, 1);
  	if (!host)
  		return -ENOMEM;
  
  	ap = host->ports[0];
  
  	/* Setup ATA bindings */
  	ap->ops	     = &at32_port_ops;
  	ap->pio_mask = PIO_MASK;
3696df309   Sergei Shtylyov   libata: remove AT...
195
  	ap->flags   |= ATA_FLAG_SLAVE_POSS;
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  
  	/*
  	 * Since all 8-bit taskfile transfers has to go on the lower
  	 * byte of the data bus and there is a bug in the SMC that
  	 * makes it impossible to alter the bus width during runtime,
  	 * we need to hardwire the address signals as follows:
  	 *
  	 *	A_IDE(2:0) <= A_EBI(3:1)
  	 *
  	 * This makes all addresses on the EBI even, thus all data
  	 * will be on the lower byte of the data bus.  All addresses
  	 * used by libATA need to be altered according to this.
  	 */
  	ap->ioaddr.altstatus_addr = info->alt_addr + (0x06 << 1);
  	ap->ioaddr.ctl_addr	  = info->alt_addr + (0x06 << 1);
  
  	ap->ioaddr.data_addr	  = info->ide_addr + (ATA_REG_DATA << 1);
  	ap->ioaddr.error_addr	  = info->ide_addr + (ATA_REG_ERR << 1);
  	ap->ioaddr.feature_addr	  = info->ide_addr + (ATA_REG_FEATURE << 1);
  	ap->ioaddr.nsect_addr	  = info->ide_addr + (ATA_REG_NSECT << 1);
  	ap->ioaddr.lbal_addr	  = info->ide_addr + (ATA_REG_LBAL << 1);
  	ap->ioaddr.lbam_addr	  = info->ide_addr + (ATA_REG_LBAM << 1);
  	ap->ioaddr.lbah_addr	  = info->ide_addr + (ATA_REG_LBAH << 1);
  	ap->ioaddr.device_addr	  = info->ide_addr + (ATA_REG_DEVICE << 1);
  	ap->ioaddr.status_addr	  = info->ide_addr + (ATA_REG_STATUS << 1);
  	ap->ioaddr.command_addr	  = info->ide_addr + (ATA_REG_CMD << 1);
  
  	/* Set info as private data of ATA host */
  	host->private_data = info;
  
  	/* Register ATA device and return */
9363c3825   Tejun Heo   libata: rename SF...
227
  	return ata_host_activate(host, info->irq, ata_sff_interrupt,
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
  				 IRQF_SHARED | IRQF_TRIGGER_RISING,
  				 &at32_sht);
  }
  
  /*
   * This function may come in handy for people analyzing their own
   * EBI -> PATA adaptors.
   */
  #ifdef DEBUG_BUS
  
  static void __init pata_at32_debug_bus(struct device *dev,
  				       struct at32_ide_info *info)
  {
  	const int d1 = 0xff;
  	const int d2 = 0x00;
  
  	int i;
  
  	/* Write 8-bit values (registers) */
  	iowrite8(d1, info->alt_addr + (0x06 << 1));
  	iowrite8(d2, info->alt_addr + (0x06 << 1));
  
  	for (i = 0; i < 8; i++) {
  		iowrite8(d1, info->ide_addr + (i << 1));
  		iowrite8(d2, info->ide_addr + (i << 1));
  	}
  
  	/* Write 16 bit values (data) */
  	iowrite16(d1,	   info->ide_addr);
  	iowrite16(d1 << 8, info->ide_addr);
  
  	iowrite16(d1,	   info->ide_addr);
  	iowrite16(d1 << 8, info->ide_addr);
  }
  
  #endif
  
  static int __init pata_at32_probe(struct platform_device *pdev)
  {
  	const struct ata_timing initial_timing =
  		{XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0};
  
  	struct device		 *dev = &pdev->dev;
  	struct at32_ide_info	 *info;
  	struct ide_platform_data *board = pdev->dev.platform_data;
  	struct resource		 *res;
  
  	int irq;
  	int ret;
  
  	if (!board)
  		return -ENXIO;
  
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	if (!res)
  		return -ENXIO;
  
  	/* Retrive IRQ */
  	irq = platform_get_irq(pdev, 0);
  	if (irq < 0)
  		return irq;
1967b7ff7   Joe Perches   drivers/ata/: Spe...
289
  	/* Setup struct containing private information */
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
290
291
292
  	info = kzalloc(sizeof(struct at32_ide_info), GFP_KERNEL);
  	if (!info)
  		return -ENOMEM;
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
  	info->irq = irq;
  	info->cs  = board->cs;
  
  	/* Request memory resources */
  	info->res_ide.start = res->start + CF_IDE_OFFSET;
  	info->res_ide.end   = info->res_ide.start + CF_RES_SIZE - 1;
  	info->res_ide.name  = "ide";
  	info->res_ide.flags = IORESOURCE_MEM;
  
  	ret = request_resource(res, &info->res_ide);
  	if (ret)
  		goto err_req_res_ide;
  
  	info->res_alt.start = res->start + CF_ALT_IDE_OFFSET;
  	info->res_alt.end   = info->res_alt.start + CF_RES_SIZE - 1;
  	info->res_alt.name  = "alt";
  	info->res_alt.flags = IORESOURCE_MEM;
  
  	ret = request_resource(res, &info->res_alt);
  	if (ret)
  		goto err_req_res_alt;
  
  	/* Setup non-timing elements of SMC */
  	info->smc.bus_width	 = 2; /* 16 bit data bus */
  	info->smc.nrd_controlled = 1; /* Sample data on rising edge of NRD */
  	info->smc.nwe_controlled = 0; /* Drive data on falling edge of NCS */
  	info->smc.nwait_mode	 = 3; /* NWAIT is in READY mode */
  	info->smc.byte_write	 = 0; /* Byte select access type */
  	info->smc.tdf_mode	 = 0; /* TDF optimization disabled */
  	info->smc.tdf_cycles	 = 0; /* No TDF wait cycles */
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
323
  	/* Setup SMC to ATA timing */
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
324
325
326
  	ret = pata_at32_setup_timing(dev, info, &initial_timing);
  	if (ret)
  		goto err_setup_timing;
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
327
  	/* Map ATA address space */
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
328
329
330
331
332
333
334
335
336
  	ret = -ENOMEM;
  	info->ide_addr = devm_ioremap(dev, info->res_ide.start, 16);
  	info->alt_addr = devm_ioremap(dev, info->res_alt.start, 16);
  	if (!info->ide_addr || !info->alt_addr)
  		goto err_ioremap;
  
  #ifdef DEBUG_BUS
  	pata_at32_debug_bus(dev, info);
  #endif
1c20a493c   Kristoffer Nyborg Gregertsen   Several fixes for...
337
  	/* Setup and register ATA device */
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  	ret = pata_at32_init_one(dev, info);
  	if (ret)
  		goto err_ata_device;
  
  	return 0;
  
   err_ata_device:
   err_ioremap:
   err_setup_timing:
  	release_resource(&info->res_alt);
   err_req_res_alt:
  	release_resource(&info->res_ide);
   err_req_res_ide:
  	kfree(info);
  
  	return ret;
  }
  
  static int __exit pata_at32_remove(struct platform_device *pdev)
  {
  	struct ata_host *host = platform_get_drvdata(pdev);
  	struct at32_ide_info *info;
  
  	if (!host)
  		return 0;
  
  	info = host->private_data;
  	ata_host_detach(host);
  
  	if (!info)
  		return 0;
  
  	release_resource(&info->res_ide);
  	release_resource(&info->res_alt);
  
  	kfree(info);
  
  	return 0;
  }
458622fcd   Kay Sievers   ATA/IDE: fix plat...
377
378
  /* work with hotplug and coldplug */
  MODULE_ALIAS("platform:at32_ide");
7c9ef8e41   Kristoffer Nyborg Gregertsen   AVR32 PATA driver
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
  static struct platform_driver pata_at32_driver = {
  	.remove	       = __exit_p(pata_at32_remove),
  	.driver	       = {
  		.name  = "at32_ide",
  		.owner = THIS_MODULE,
  	},
  };
  
  static int __init pata_at32_init(void)
  {
  	return platform_driver_probe(&pata_at32_driver, pata_at32_probe);
  }
  
  static void __exit pata_at32_exit(void)
  {
  	platform_driver_unregister(&pata_at32_driver);
  }
  
  module_init(pata_at32_init);
  module_exit(pata_at32_exit);
  
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("AVR32 SMC/CFC PATA Driver");
  MODULE_AUTHOR("Kristoffer Nyborg Gregertsen <kngregertsen@norway.atmel.com>");
  MODULE_VERSION(DRV_VERSION);