Blame view

drivers/ata/sata_fsl.c 37.7 KB
faf0b2e5a   Li Yang   drivers/ata: add ...
1
2
3
4
5
6
7
8
  /*
   * drivers/ata/sata_fsl.c
   *
   * Freescale 3.0Gbps SATA device driver
   *
   * Author: Ashish Kalra <ashish.kalra@freescale.com>
   * Li Yang <leoli@freescale.com>
   *
2f957fc95   Xulei   ATA: Add FSL sata...
9
   * Copyright (c) 2006-2007, 2011 Freescale Semiconductor, Inc.
faf0b2e5a   Li Yang   drivers/ata: add ...
10
11
12
13
14
15
16
17
18
19
20
   *
   * This program is free software; you can redistribute  it and/or modify it
   * under  the terms of  the GNU General  Public License as published by the
   * Free Software Foundation;  either version 2 of the  License, or (at your
   * option) any later version.
   *
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/platform_device.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
21
  #include <linux/slab.h>
faf0b2e5a   Li Yang   drivers/ata: add ...
22
23
24
25
26
27
28
29
30
31
32
33
34
  
  #include <scsi/scsi_host.h>
  #include <scsi/scsi_cmnd.h>
  #include <linux/libata.h>
  #include <asm/io.h>
  #include <linux/of_platform.h>
  
  /* Controller information */
  enum {
  	SATA_FSL_QUEUE_DEPTH	= 16,
  	SATA_FSL_MAX_PRD	= 63,
  	SATA_FSL_MAX_PRD_USABLE	= SATA_FSL_MAX_PRD - 1,
  	SATA_FSL_MAX_PRD_DIRECT	= 16,	/* Direct PRDT entries */
9cbe056f6   Sergei Shtylyov   libata: remove AT...
35
36
  	SATA_FSL_HOST_FLAGS	= (ATA_FLAG_SATA | ATA_FLAG_PIO_DMA |
  				ATA_FLAG_PMP | ATA_FLAG_NCQ | ATA_FLAG_AN),
faf0b2e5a   Li Yang   drivers/ata: add ...
37
38
39
40
41
42
43
  
  	SATA_FSL_MAX_CMDS	= SATA_FSL_QUEUE_DEPTH,
  	SATA_FSL_CMD_HDR_SIZE	= 16,	/* 4 DWORDS */
  	SATA_FSL_CMD_SLOT_SIZE  = (SATA_FSL_MAX_CMDS * SATA_FSL_CMD_HDR_SIZE),
  
  	/*
  	 * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and
25985edce   Lucas De Marchi   Fix common misspe...
44
  	 * chained indirect PRDEs up to a max count of 63.
af901ca18   André Goddard Rosa   tree-wide: fix as...
45
  	 * We are allocating an array of 63 PRDEs contiguously, but PRDE#15 will
faf0b2e5a   Li Yang   drivers/ata: add ...
46
  	 * be setup as an indirect descriptor, pointing to it's next
af901ca18   André Goddard Rosa   tree-wide: fix as...
47
  	 * (contiguous) PRDE. Though chained indirect PRDE arrays are
faf0b2e5a   Li Yang   drivers/ata: add ...
48
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  	 * supported,it will be more efficient to use a direct PRDT and
  	 * a single chain/link to indirect PRDE array/PRDT.
  	 */
  
  	SATA_FSL_CMD_DESC_CFIS_SZ	= 32,
  	SATA_FSL_CMD_DESC_SFIS_SZ	= 32,
  	SATA_FSL_CMD_DESC_ACMD_SZ	= 16,
  	SATA_FSL_CMD_DESC_RSRVD		= 16,
  
  	SATA_FSL_CMD_DESC_SIZE	= (SATA_FSL_CMD_DESC_CFIS_SZ +
  				 SATA_FSL_CMD_DESC_SFIS_SZ +
  				 SATA_FSL_CMD_DESC_ACMD_SZ +
  				 SATA_FSL_CMD_DESC_RSRVD +
  				 SATA_FSL_MAX_PRD * 16),
  
  	SATA_FSL_CMD_DESC_OFFSET_TO_PRDT	=
  				(SATA_FSL_CMD_DESC_CFIS_SZ +
  				 SATA_FSL_CMD_DESC_SFIS_SZ +
  				 SATA_FSL_CMD_DESC_ACMD_SZ +
  				 SATA_FSL_CMD_DESC_RSRVD),
  
  	SATA_FSL_CMD_DESC_AR_SZ	= (SATA_FSL_CMD_DESC_SIZE * SATA_FSL_MAX_CMDS),
  	SATA_FSL_PORT_PRIV_DMA_SZ = (SATA_FSL_CMD_SLOT_SIZE +
  					SATA_FSL_CMD_DESC_AR_SZ),
  
  	/*
  	 * MPC8315 has two SATA controllers, SATA1 & SATA2
  	 * (one port per controller)
  	 * MPC837x has 2/4 controllers, one port per controller
  	 */
  
  	SATA_FSL_MAX_PORTS	= 1,
  
  	SATA_FSL_IRQ_FLAG	= IRQF_SHARED,
  };
  
  /*
  * Host Controller command register set - per port
  */
  enum {
  	CQ = 0,
  	CA = 8,
  	CC = 0x10,
  	CE = 0x18,
  	DE = 0x20,
  	CHBA = 0x24,
  	HSTATUS = 0x28,
  	HCONTROL = 0x2C,
  	CQPMP = 0x30,
  	SIGNATURE = 0x34,
  	ICC = 0x38,
  
  	/*
  	 * Host Status Register (HStatus) bitdefs
  	 */
  	ONLINE = (1 << 31),
  	GOING_OFFLINE = (1 << 30),
  	BIST_ERR = (1 << 29),
  
  	FATAL_ERR_HC_MASTER_ERR = (1 << 18),
  	FATAL_ERR_PARITY_ERR_TX = (1 << 17),
  	FATAL_ERR_PARITY_ERR_RX = (1 << 16),
  	FATAL_ERR_DATA_UNDERRUN = (1 << 13),
  	FATAL_ERR_DATA_OVERRUN = (1 << 12),
  	FATAL_ERR_CRC_ERR_TX = (1 << 11),
  	FATAL_ERR_CRC_ERR_RX = (1 << 10),
  	FATAL_ERR_FIFO_OVRFL_TX = (1 << 9),
  	FATAL_ERR_FIFO_OVRFL_RX = (1 << 8),
  
  	FATAL_ERROR_DECODE = FATAL_ERR_HC_MASTER_ERR |
  	    FATAL_ERR_PARITY_ERR_TX |
  	    FATAL_ERR_PARITY_ERR_RX |
  	    FATAL_ERR_DATA_UNDERRUN |
  	    FATAL_ERR_DATA_OVERRUN |
  	    FATAL_ERR_CRC_ERR_TX |
  	    FATAL_ERR_CRC_ERR_RX |
  	    FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX,
  
  	INT_ON_FATAL_ERR = (1 << 5),
  	INT_ON_PHYRDY_CHG = (1 << 4),
  
  	INT_ON_SIGNATURE_UPDATE = (1 << 3),
  	INT_ON_SNOTIFY_UPDATE = (1 << 2),
  	INT_ON_SINGL_DEVICE_ERR = (1 << 1),
  	INT_ON_CMD_COMPLETE = 1,
fd6c29e3d   ashish kalra   sata_fsl: Add asy...
133
  	INT_ON_ERROR = INT_ON_FATAL_ERR | INT_ON_SNOTIFY_UPDATE |
faf0b2e5a   Li Yang   drivers/ata: add ...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  	    INT_ON_PHYRDY_CHG | INT_ON_SINGL_DEVICE_ERR,
  
  	/*
  	 * Host Control Register (HControl) bitdefs
  	 */
  	HCONTROL_ONLINE_PHY_RST = (1 << 31),
  	HCONTROL_FORCE_OFFLINE = (1 << 30),
  	HCONTROL_PARITY_PROT_MOD = (1 << 14),
  	HCONTROL_DPATH_PARITY = (1 << 12),
  	HCONTROL_SNOOP_ENABLE = (1 << 10),
  	HCONTROL_PMP_ATTACHED = (1 << 9),
  	HCONTROL_COPYOUT_STATFIS = (1 << 8),
  	IE_ON_FATAL_ERR = (1 << 5),
  	IE_ON_PHYRDY_CHG = (1 << 4),
  	IE_ON_SIGNATURE_UPDATE = (1 << 3),
  	IE_ON_SNOTIFY_UPDATE = (1 << 2),
  	IE_ON_SINGL_DEVICE_ERR = (1 << 1),
  	IE_ON_CMD_COMPLETE = 1,
  
  	DEFAULT_PORT_IRQ_ENABLE_MASK = IE_ON_FATAL_ERR | IE_ON_PHYRDY_CHG |
fd6c29e3d   ashish kalra   sata_fsl: Add asy...
154
  	    IE_ON_SIGNATURE_UPDATE | IE_ON_SNOTIFY_UPDATE |
faf0b2e5a   Li Yang   drivers/ata: add ...
155
156
157
  	    IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,
  
  	EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31),
2f957fc95   Xulei   ATA: Add FSL sata...
158
159
  	DATA_SNOOP_ENABLE_V1 = (1 << 22),
  	DATA_SNOOP_ENABLE_V2 = (1 << 28),
faf0b2e5a   Li Yang   drivers/ata: add ...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  };
  
  /*
   * SATA Superset Registers
   */
  enum {
  	SSTATUS = 0,
  	SERROR = 4,
  	SCONTROL = 8,
  	SNOTIFY = 0xC,
  };
  
  /*
   * Control Status Register Set
   */
  enum {
  	TRANSCFG = 0,
  	TRANSSTATUS = 4,
  	LINKCFG = 8,
  	LINKCFG1 = 0xC,
  	LINKCFG2 = 0x10,
  	LINKSTATUS = 0x14,
  	LINKSTATUS1 = 0x18,
  	PHYCTRLCFG = 0x1C,
  	COMMANDSTAT = 0x20,
  };
578ca87c9   Prabhakar Kushwaha   sata_fsl: Update ...
186
187
188
189
  /* TRANSCFG (transport-layer) configuration control */
  enum {
  	TRANSCFG_RX_WATER_MARK = (1 << 4),
  };
faf0b2e5a   Li Yang   drivers/ata: add ...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  /* PHY (link-layer) configuration control */
  enum {
  	PHY_BIST_ENABLE = 0x01,
  };
  
  /*
   * Command Header Table entry, i.e, command slot
   * 4 Dwords per command slot, command header size ==  64 Dwords.
   */
  struct cmdhdr_tbl_entry {
  	u32 cda;
  	u32 prde_fis_len;
  	u32 ttl;
  	u32 desc_info;
  };
  
  /*
   * Description information bitdefs
   */
  enum {
d35872438   Dave Liu   sata_fsl: Fix the...
210
  	CMD_DESC_RES = (1 << 11),
faf0b2e5a   Li Yang   drivers/ata: add ...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  	VENDOR_SPECIFIC_BIST = (1 << 10),
  	CMD_DESC_SNOOP_ENABLE = (1 << 9),
  	FPDMA_QUEUED_CMD = (1 << 8),
  	SRST_CMD = (1 << 7),
  	BIST = (1 << 6),
  	ATAPI_CMD = (1 << 5),
  };
  
  /*
   * Command Descriptor
   */
  struct command_desc {
  	u8 cfis[8 * 4];
  	u8 sfis[8 * 4];
  	u8 acmd[4 * 4];
  	u8 fill[4 * 4];
  	u32 prdt[SATA_FSL_MAX_PRD_DIRECT * 4];
  	u32 prdt_indirect[(SATA_FSL_MAX_PRD - SATA_FSL_MAX_PRD_DIRECT) * 4];
  };
  
  /*
   * Physical region table descriptor(PRD)
   */
  
  struct prde {
  	u32 dba;
  	u8 fill[2 * 4];
  	u32 ddc_and_ext;
  };
  
  /*
   * ata_port private data
   * This is our per-port instance data.
   */
  struct sata_fsl_port_priv {
  	struct cmdhdr_tbl_entry *cmdslot;
  	dma_addr_t cmdslot_paddr;
  	struct command_desc *cmdentry;
  	dma_addr_t cmdentry_paddr;
faf0b2e5a   Li Yang   drivers/ata: add ...
250
251
252
253
254
255
256
257
258
  };
  
  /*
   * ata_port->host_set private data
   */
  struct sata_fsl_host_priv {
  	void __iomem *hcr_base;
  	void __iomem *ssr_base;
  	void __iomem *csr_base;
79b3edc97   Li Yang   ata/sata_fsl: sav...
259
  	int irq;
2f957fc95   Xulei   ATA: Add FSL sata...
260
  	int data_snoop;
faf0b2e5a   Li Yang   drivers/ata: add ...
261
262
263
  };
  
  static inline unsigned int sata_fsl_tag(unsigned int tag,
520d3a1a8   Li Yang   ata/sata_fsl: cle...
264
  					void __iomem *hcr_base)
faf0b2e5a   Li Yang   drivers/ata: add ...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
  {
  	/* We let libATA core do actual (queue) tag allocation */
  
  	/* all non NCQ/queued commands should have tag#0 */
  	if (ata_tag_internal(tag)) {
  		DPRINTK("mapping internal cmds to tag#0
  ");
  		return 0;
  	}
  
  	if (unlikely(tag >= SATA_FSL_QUEUE_DEPTH)) {
  		DPRINTK("tag %d invalid : out of range
  ", tag);
  		return 0;
  	}
  
  	if (unlikely((ioread32(hcr_base + CQ)) & (1 << tag))) {
  		DPRINTK("tag %d invalid : in use!!
  ", tag);
  		return 0;
  	}
  
  	return tag;
  }
  
  static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp,
  					 unsigned int tag, u32 desc_info,
  					 u32 data_xfer_len, u8 num_prde,
  					 u8 fis_len)
  {
  	dma_addr_t cmd_descriptor_address;
  
  	cmd_descriptor_address = pp->cmdentry_paddr +
  	    tag * SATA_FSL_CMD_DESC_SIZE;
  
  	/* NOTE: both data_xfer_len & fis_len are Dword counts */
  
  	pp->cmdslot[tag].cda = cpu_to_le32(cmd_descriptor_address);
  	pp->cmdslot[tag].prde_fis_len =
  	    cpu_to_le32((num_prde << 16) | (fis_len << 2));
  	pp->cmdslot[tag].ttl = cpu_to_le32(data_xfer_len & ~0x03);
520d3a1a8   Li Yang   ata/sata_fsl: cle...
306
  	pp->cmdslot[tag].desc_info = cpu_to_le32(desc_info | (tag & 0x1F));
faf0b2e5a   Li Yang   drivers/ata: add ...
307
308
309
310
311
312
313
314
315
316
  
  	VPRINTK("cda=0x%x, prde_fis_len=0x%x, ttl=0x%x, di=0x%x
  ",
  		pp->cmdslot[tag].cda,
  		pp->cmdslot[tag].prde_fis_len,
  		pp->cmdslot[tag].ttl, pp->cmdslot[tag].desc_info);
  
  }
  
  static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
2f957fc95   Xulei   ATA: Add FSL sata...
317
318
  				     u32 *ttl, dma_addr_t cmd_desc_paddr,
  				     int data_snoop)
faf0b2e5a   Li Yang   drivers/ata: add ...
319
320
321
322
323
324
  {
  	struct scatterlist *sg;
  	unsigned int num_prde = 0;
  	u32 ttl_dwords = 0;
  
  	/*
af901ca18   André Goddard Rosa   tree-wide: fix as...
325
  	 * NOTE : direct & indirect prdt's are contiguously allocated
faf0b2e5a   Li Yang   drivers/ata: add ...
326
327
328
329
330
331
332
  	 */
  	struct prde *prd = (struct prde *)&((struct command_desc *)
  					    cmd_desc)->prdt;
  
  	struct prde *prd_ptr_to_indirect_ext = NULL;
  	unsigned indirect_ext_segment_sz = 0;
  	dma_addr_t indirect_ext_segment_paddr;
ff2aeb1eb   Tejun Heo   libata: convert t...
333
  	unsigned int si;
faf0b2e5a   Li Yang   drivers/ata: add ...
334

b1f5dc48e   Anton Vorontsov   sata_fsl: fix bui...
335
336
  	VPRINTK("SATA FSL : cd = 0x%p, prd = 0x%p
  ", cmd_desc, prd);
faf0b2e5a   Li Yang   drivers/ata: add ...
337
338
339
  
  	indirect_ext_segment_paddr = cmd_desc_paddr +
  	    SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16;
ff2aeb1eb   Tejun Heo   libata: convert t...
340
  	for_each_sg(qc->sg, sg, qc->n_elem, si) {
faf0b2e5a   Li Yang   drivers/ata: add ...
341
342
  		dma_addr_t sg_addr = sg_dma_address(sg);
  		u32 sg_len = sg_dma_len(sg);
f48c019f1   Kumar Gala   sata_fsl: Fix com...
343
344
345
  		VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%llx, sg_len = %d
  ",
  			(unsigned long long)sg_addr, sg_len);
faf0b2e5a   Li Yang   drivers/ata: add ...
346
347
348
  
  		/* warn if each s/g element is not dword aligned */
  		if (sg_addr & 0x03)
a9a79dfec   Joe Perches   ata: Convert ata_...
349
350
351
  			ata_port_err(qc->ap, "s/g addr unaligned : 0x%llx
  ",
  				     (unsigned long long)sg_addr);
faf0b2e5a   Li Yang   drivers/ata: add ...
352
  		if (sg_len & 0x03)
a9a79dfec   Joe Perches   ata: Convert ata_...
353
354
355
  			ata_port_err(qc->ap, "s/g len unaligned : 0x%x
  ",
  				     sg_len);
faf0b2e5a   Li Yang   drivers/ata: add ...
356

37198e305   James Bottomley   libata: kill now ...
357
358
  		if (num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1) &&
  		    sg_next(sg) != NULL) {
faf0b2e5a   Li Yang   drivers/ata: add ...
359
360
361
362
363
364
365
366
367
368
369
  			VPRINTK("setting indirect prde
  ");
  			prd_ptr_to_indirect_ext = prd;
  			prd->dba = cpu_to_le32(indirect_ext_segment_paddr);
  			indirect_ext_segment_sz = 0;
  			++prd;
  			++num_prde;
  		}
  
  		ttl_dwords += sg_len;
  		prd->dba = cpu_to_le32(sg_addr);
2f957fc95   Xulei   ATA: Add FSL sata...
370
  		prd->ddc_and_ext = cpu_to_le32(data_snoop | (sg_len & ~0x03));
faf0b2e5a   Li Yang   drivers/ata: add ...
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
  
  		VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x
  ",
  			ttl_dwords, prd->dba, prd->ddc_and_ext);
  
  		++num_prde;
  		++prd;
  		if (prd_ptr_to_indirect_ext)
  			indirect_ext_segment_sz += sg_len;
  	}
  
  	if (prd_ptr_to_indirect_ext) {
  		/* set indirect extension flag along with indirect ext. size */
  		prd_ptr_to_indirect_ext->ddc_and_ext =
  		    cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG |
2f957fc95   Xulei   ATA: Add FSL sata...
386
  				 data_snoop |
faf0b2e5a   Li Yang   drivers/ata: add ...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
  				 (indirect_ext_segment_sz & ~0x03)));
  	}
  
  	*ttl = ttl_dwords;
  	return num_prde;
  }
  
  static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)
  {
  	struct ata_port *ap = qc->ap;
  	struct sata_fsl_port_priv *pp = ap->private_data;
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
  	struct command_desc *cd;
d35872438   Dave Liu   sata_fsl: Fix the...
402
  	u32 desc_info = CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE;
faf0b2e5a   Li Yang   drivers/ata: add ...
403
404
405
406
407
408
  	u32 num_prde = 0;
  	u32 ttl_dwords = 0;
  	dma_addr_t cd_paddr;
  
  	cd = (struct command_desc *)pp->cmdentry + tag;
  	cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE;
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
409
  	ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *) &cd->cfis);
faf0b2e5a   Li Yang   drivers/ata: add ...
410
411
412
413
414
415
416
417
418
419
420
421
  
  	VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x
  ",
  		cd->cfis[0], cd->cfis[1], cd->cfis[2]);
  
  	if (qc->tf.protocol == ATA_PROT_NCQ) {
  		VPRINTK("FPDMA xfer,Sctor cnt[0:7],[8:15] = %d,%d
  ",
  			cd->cfis[3], cd->cfis[11]);
  	}
  
  	/* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */
405e66b38   Tejun Heo   libata: implement...
422
  	if (ata_is_atapi(qc->tf.protocol)) {
faf0b2e5a   Li Yang   drivers/ata: add ...
423
424
425
426
427
428
429
  		desc_info |= ATAPI_CMD;
  		memset((void *)&cd->acmd, 0, 32);
  		memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len);
  	}
  
  	if (qc->flags & ATA_QCFLAG_DMAMAP)
  		num_prde = sata_fsl_fill_sg(qc, (void *)cd,
2f957fc95   Xulei   ATA: Add FSL sata...
430
431
  					    &ttl_dwords, cd_paddr,
  					    host_priv->data_snoop);
faf0b2e5a   Li Yang   drivers/ata: add ...
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
  
  	if (qc->tf.protocol == ATA_PROT_NCQ)
  		desc_info |= FPDMA_QUEUED_CMD;
  
  	sata_fsl_setup_cmd_hdr_entry(pp, tag, desc_info, ttl_dwords,
  				     num_prde, 5);
  
  	VPRINTK("SATA FSL : xx_qc_prep, di = 0x%x, ttl = %d, num_prde = %d
  ",
  		desc_info, ttl_dwords, num_prde);
  }
  
  static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc)
  {
  	struct ata_port *ap = qc->ap;
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
  
  	VPRINTK("xx_qc_issue called,CQ=0x%x,CA=0x%x,CE=0x%x,CC=0x%x
  ",
  		ioread32(CQ + hcr_base),
  		ioread32(CA + hcr_base),
  		ioread32(CE + hcr_base), ioread32(CC + hcr_base));
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
456
  	iowrite32(qc->dev->link->pmp, CQPMP + hcr_base);
faf0b2e5a   Li Yang   drivers/ata: add ...
457
458
459
460
461
462
463
464
465
466
467
  	/* Simply queue command to the controller/device */
  	iowrite32(1 << tag, CQ + hcr_base);
  
  	VPRINTK("xx_qc_issue called, tag=%d, CQ=0x%x, CA=0x%x
  ",
  		tag, ioread32(CQ + hcr_base), ioread32(CA + hcr_base));
  
  	VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x
  ",
  		ioread32(CE + hcr_base),
  		ioread32(DE + hcr_base),
b1f5dc48e   Anton Vorontsov   sata_fsl: fix bui...
468
469
  		ioread32(CC + hcr_base),
  		ioread32(COMMANDSTAT + host_priv->csr_base));
faf0b2e5a   Li Yang   drivers/ata: add ...
470
471
472
  
  	return 0;
  }
4c9bf4e79   Tejun Heo   libata: replace t...
473
474
475
476
477
478
479
480
481
482
483
484
485
  static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc)
  {
  	struct sata_fsl_port_priv *pp = qc->ap->private_data;
  	struct sata_fsl_host_priv *host_priv = qc->ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
  	struct command_desc *cd;
  
  	cd = pp->cmdentry + tag;
  
  	ata_tf_from_fis(cd->sfis, &qc->result_tf);
  	return true;
  }
82ef04fb4   Tejun Heo   libata: make SCR ...
486
487
  static int sata_fsl_scr_write(struct ata_link *link,
  			      unsigned int sc_reg_in, u32 val)
faf0b2e5a   Li Yang   drivers/ata: add ...
488
  {
82ef04fb4   Tejun Heo   libata: make SCR ...
489
  	struct sata_fsl_host_priv *host_priv = link->ap->host->private_data;
faf0b2e5a   Li Yang   drivers/ata: add ...
490
491
492
493
494
  	void __iomem *ssr_base = host_priv->ssr_base;
  	unsigned int sc_reg;
  
  	switch (sc_reg_in) {
  	case SCR_STATUS:
faf0b2e5a   Li Yang   drivers/ata: add ...
495
  	case SCR_ERROR:
faf0b2e5a   Li Yang   drivers/ata: add ...
496
  	case SCR_CONTROL:
faf0b2e5a   Li Yang   drivers/ata: add ...
497
  	case SCR_ACTIVE:
9465d5324   Jeff Garzik   ata/sata_fsl: Rem...
498
  		sc_reg = sc_reg_in;
faf0b2e5a   Li Yang   drivers/ata: add ...
499
500
501
502
503
504
505
  		break;
  	default:
  		return -EINVAL;
  	}
  
  	VPRINTK("xx_scr_write, reg_in = %d
  ", sc_reg);
2a52e8d4e   Jeff Garzik   ata/sata_fsl: cle...
506
  	iowrite32(val, ssr_base + (sc_reg * 4));
faf0b2e5a   Li Yang   drivers/ata: add ...
507
508
  	return 0;
  }
82ef04fb4   Tejun Heo   libata: make SCR ...
509
510
  static int sata_fsl_scr_read(struct ata_link *link,
  			     unsigned int sc_reg_in, u32 *val)
faf0b2e5a   Li Yang   drivers/ata: add ...
511
  {
82ef04fb4   Tejun Heo   libata: make SCR ...
512
  	struct sata_fsl_host_priv *host_priv = link->ap->host->private_data;
faf0b2e5a   Li Yang   drivers/ata: add ...
513
514
515
516
517
  	void __iomem *ssr_base = host_priv->ssr_base;
  	unsigned int sc_reg;
  
  	switch (sc_reg_in) {
  	case SCR_STATUS:
faf0b2e5a   Li Yang   drivers/ata: add ...
518
  	case SCR_ERROR:
faf0b2e5a   Li Yang   drivers/ata: add ...
519
  	case SCR_CONTROL:
faf0b2e5a   Li Yang   drivers/ata: add ...
520
  	case SCR_ACTIVE:
9465d5324   Jeff Garzik   ata/sata_fsl: Rem...
521
  		sc_reg = sc_reg_in;
faf0b2e5a   Li Yang   drivers/ata: add ...
522
523
524
525
526
527
528
  		break;
  	default:
  		return -EINVAL;
  	}
  
  	VPRINTK("xx_scr_read, reg_in = %d
  ", sc_reg);
2a52e8d4e   Jeff Garzik   ata/sata_fsl: cle...
529
  	*val = ioread32(ssr_base + (sc_reg * 4));
faf0b2e5a   Li Yang   drivers/ata: add ...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
  	return 0;
  }
  
  static void sata_fsl_freeze(struct ata_port *ap)
  {
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 temp;
  
  	VPRINTK("xx_freeze, CQ=0x%x, CA=0x%x, CE=0x%x, DE=0x%x
  ",
  		ioread32(CQ + hcr_base),
  		ioread32(CA + hcr_base),
  		ioread32(CE + hcr_base), ioread32(DE + hcr_base));
b1f5dc48e   Anton Vorontsov   sata_fsl: fix bui...
544
545
546
  	VPRINTK("CmdStat = 0x%x
  ",
  		ioread32(host_priv->csr_base + COMMANDSTAT));
faf0b2e5a   Li Yang   drivers/ata: add ...
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
  
  	/* disable interrupts on the controller/port */
  	temp = ioread32(hcr_base + HCONTROL);
  	iowrite32((temp & ~0x3F), hcr_base + HCONTROL);
  
  	VPRINTK("in xx_freeze : HControl = 0x%x, HStatus = 0x%x
  ",
  		ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
  }
  
  static void sata_fsl_thaw(struct ata_port *ap)
  {
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 temp;
  
  	/* ack. any pending IRQs for this controller/port */
  	temp = ioread32(hcr_base + HSTATUS);
  
  	VPRINTK("xx_thaw, pending IRQs = 0x%x
  ", (temp & 0x3F));
  
  	if (temp & 0x3F)
  		iowrite32((temp & 0x3F), hcr_base + HSTATUS);
  
  	/* enable interrupts on the controller/port */
  	temp = ioread32(hcr_base + HCONTROL);
  	iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL);
  
  	VPRINTK("xx_thaw : HControl = 0x%x, HStatus = 0x%x
  ",
  		ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
  }
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
  static void sata_fsl_pmp_attach(struct ata_port *ap)
  {
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 temp;
  
  	temp = ioread32(hcr_base + HCONTROL);
  	iowrite32((temp | HCONTROL_PMP_ATTACHED), hcr_base + HCONTROL);
  }
  
  static void sata_fsl_pmp_detach(struct ata_port *ap)
  {
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 temp;
  
  	temp = ioread32(hcr_base + HCONTROL);
  	temp &= ~HCONTROL_PMP_ATTACHED;
  	iowrite32(temp, hcr_base + HCONTROL);
  
  	/* enable interrupts on the controller/port */
  	temp = ioread32(hcr_base + HCONTROL);
  	iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL);
  
  }
faf0b2e5a   Li Yang   drivers/ata: add ...
605
606
607
608
  static int sata_fsl_port_start(struct ata_port *ap)
  {
  	struct device *dev = ap->host->dev;
  	struct sata_fsl_port_priv *pp;
faf0b2e5a   Li Yang   drivers/ata: add ...
609
610
611
612
613
614
615
616
617
  	void *mem;
  	dma_addr_t mem_dma;
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 temp;
  
  	pp = kzalloc(sizeof(*pp), GFP_KERNEL);
  	if (!pp)
  		return -ENOMEM;
faf0b2e5a   Li Yang   drivers/ata: add ...
618
619
620
  	mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma,
  				 GFP_KERNEL);
  	if (!mem) {
faf0b2e5a   Li Yang   drivers/ata: add ...
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
  		kfree(pp);
  		return -ENOMEM;
  	}
  	memset(mem, 0, SATA_FSL_PORT_PRIV_DMA_SZ);
  
  	pp->cmdslot = mem;
  	pp->cmdslot_paddr = mem_dma;
  
  	mem += SATA_FSL_CMD_SLOT_SIZE;
  	mem_dma += SATA_FSL_CMD_SLOT_SIZE;
  
  	pp->cmdentry = mem;
  	pp->cmdentry_paddr = mem_dma;
  
  	ap->private_data = pp;
  
  	VPRINTK("CHBA = 0x%x, cmdentry_phys = 0x%x
  ",
  		pp->cmdslot_paddr, pp->cmdentry_paddr);
  
  	/* Now, update the CHBA register in host controller cmd register set */
  	iowrite32(pp->cmdslot_paddr & 0xffffffff, hcr_base + CHBA);
  
  	/*
  	 * Now, we can bring the controller on-line & also initiate
  	 * the COMINIT sequence, we simply return here and the boot-probing
  	 * & device discovery process is re-initiated by libATA using a
  	 * Softreset EH (dummy) session. Hence, boot probing and device
  	 * discovey will be part of sata_fsl_softreset() callback.
  	 */
  
  	temp = ioread32(hcr_base + HCONTROL);
  	iowrite32((temp | HCONTROL_ONLINE_PHY_RST), hcr_base + HCONTROL);
  
  	VPRINTK("HStatus = 0x%x
  ", ioread32(hcr_base + HSTATUS));
  	VPRINTK("HControl = 0x%x
  ", ioread32(hcr_base + HCONTROL));
  	VPRINTK("CHBA  = 0x%x
  ", ioread32(hcr_base + CHBA));
e7eac96e8   ashish kalra   ata/sata_fsl: Mov...
661
  #ifdef CONFIG_MPC8315_DS
faf0b2e5a   Li Yang   drivers/ata: add ...
662
663
664
665
  	/*
  	 * Workaround for 8315DS board 3gbps link-up issue,
  	 * currently limit SATA port to GEN1 speed
  	 */
82ef04fb4   Tejun Heo   libata: make SCR ...
666
  	sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
faf0b2e5a   Li Yang   drivers/ata: add ...
667
668
  	temp &= ~(0xF << 4);
  	temp |= (0x1 << 4);
82ef04fb4   Tejun Heo   libata: make SCR ...
669
  	sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);
faf0b2e5a   Li Yang   drivers/ata: add ...
670

82ef04fb4   Tejun Heo   libata: make SCR ...
671
  	sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
a44fec1fc   Joe Perches   ata: Convert dev_...
672
673
  	dev_warn(dev, "scr_control, speed limited to %x
  ", temp);
e7eac96e8   ashish kalra   ata/sata_fsl: Mov...
674
  #endif
faf0b2e5a   Li Yang   drivers/ata: add ...
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  
  	return 0;
  }
  
  static void sata_fsl_port_stop(struct ata_port *ap)
  {
  	struct device *dev = ap->host->dev;
  	struct sata_fsl_port_priv *pp = ap->private_data;
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 temp;
  
  	/*
  	 * Force host controller to go off-line, aborting current operations
  	 */
  	temp = ioread32(hcr_base + HCONTROL);
  	temp &= ~HCONTROL_ONLINE_PHY_RST;
  	temp |= HCONTROL_FORCE_OFFLINE;
  	iowrite32(temp, hcr_base + HCONTROL);
  
  	/* Poll for controller to go offline - should happen immediately */
97750cebb   Tejun Heo   libata: add @ap t...
696
  	ata_wait_register(ap, hcr_base + HSTATUS, ONLINE, ONLINE, 1, 1);
faf0b2e5a   Li Yang   drivers/ata: add ...
697
698
699
700
  
  	ap->private_data = NULL;
  	dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ,
  			  pp->cmdslot, pp->cmdslot_paddr);
faf0b2e5a   Li Yang   drivers/ata: add ...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
  	kfree(pp);
  }
  
  static unsigned int sata_fsl_dev_classify(struct ata_port *ap)
  {
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	struct ata_taskfile tf;
  	u32 temp;
  
  	temp = ioread32(hcr_base + SIGNATURE);
  
  	VPRINTK("raw sig = 0x%x
  ", temp);
  	VPRINTK("HStatus = 0x%x
  ", ioread32(hcr_base + HSTATUS));
  	VPRINTK("HControl = 0x%x
  ", ioread32(hcr_base + HCONTROL));
  
  	tf.lbah = (temp >> 24) & 0xff;
  	tf.lbam = (temp >> 16) & 0xff;
  	tf.lbal = (temp >> 8) & 0xff;
  	tf.nsect = temp & 0xff;
  
  	return ata_dev_classify(&tf);
  }
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
727
  static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
728
  					unsigned long deadline)
faf0b2e5a   Li Yang   drivers/ata: add ...
729
  {
1bf617b71   Li Yang   ata/sata_fsl: Upd...
730
  	struct ata_port *ap = link->ap;
faf0b2e5a   Li Yang   drivers/ata: add ...
731
732
733
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 temp;
faf0b2e5a   Li Yang   drivers/ata: add ...
734
  	int i = 0;
faf0b2e5a   Li Yang   drivers/ata: add ...
735
  	unsigned long start_jiffies;
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
736
737
  	DPRINTK("in xx_hardreset
  ");
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
738

faf0b2e5a   Li Yang   drivers/ata: add ...
739
740
741
742
743
744
745
746
747
  try_offline_again:
  	/*
  	 * Force host controller to go off-line, aborting current operations
  	 */
  	temp = ioread32(hcr_base + HCONTROL);
  	temp &= ~HCONTROL_ONLINE_PHY_RST;
  	iowrite32(temp, hcr_base + HCONTROL);
  
  	/* Poll for controller to go offline */
97750cebb   Tejun Heo   libata: add @ap t...
748
749
  	temp = ata_wait_register(ap, hcr_base + HSTATUS, ONLINE, ONLINE,
  				 1, 500);
faf0b2e5a   Li Yang   drivers/ata: add ...
750
751
  
  	if (temp & ONLINE) {
a9a79dfec   Joe Perches   ata: Convert ata_...
752
753
  		ata_port_err(ap, "Hardreset failed, not off-lined %d
  ", i);
faf0b2e5a   Li Yang   drivers/ata: add ...
754
755
756
757
758
759
760
761
762
763
  
  		/*
  		 * Try to offline controller atleast twice
  		 */
  		i++;
  		if (i == 2)
  			goto err;
  		else
  			goto try_offline_again;
  	}
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
764
765
  	DPRINTK("hardreset, controller off-lined
  ");
faf0b2e5a   Li Yang   drivers/ata: add ...
766
767
768
769
770
771
772
773
  	VPRINTK("HStatus = 0x%x
  ", ioread32(hcr_base + HSTATUS));
  	VPRINTK("HControl = 0x%x
  ", ioread32(hcr_base + HCONTROL));
  
  	/*
  	 * PHY reset should remain asserted for atleast 1ms
  	 */
97750cebb   Tejun Heo   libata: add @ap t...
774
  	ata_msleep(ap, 1);
faf0b2e5a   Li Yang   drivers/ata: add ...
775
776
777
778
779
780
781
782
783
784
  
  	/*
  	 * Now, bring the host controller online again, this can take time
  	 * as PHY reset and communication establishment, 1st D2H FIS and
  	 * device signature update is done, on safe side assume 500ms
  	 * NOTE : Host online status may be indicated immediately!!
  	 */
  
  	temp = ioread32(hcr_base + HCONTROL);
  	temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE);
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
785
  	temp |= HCONTROL_PMP_ATTACHED;
faf0b2e5a   Li Yang   drivers/ata: add ...
786
  	iowrite32(temp, hcr_base + HCONTROL);
97750cebb   Tejun Heo   libata: add @ap t...
787
  	temp = ata_wait_register(ap, hcr_base + HSTATUS, ONLINE, 0, 1, 500);
faf0b2e5a   Li Yang   drivers/ata: add ...
788
789
  
  	if (!(temp & ONLINE)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
790
791
  		ata_port_err(ap, "Hardreset failed, not on-lined
  ");
faf0b2e5a   Li Yang   drivers/ata: add ...
792
793
  		goto err;
  	}
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
794
795
  	DPRINTK("hardreset, controller off-lined & on-lined
  ");
faf0b2e5a   Li Yang   drivers/ata: add ...
796
797
798
799
800
801
802
803
804
805
  	VPRINTK("HStatus = 0x%x
  ", ioread32(hcr_base + HSTATUS));
  	VPRINTK("HControl = 0x%x
  ", ioread32(hcr_base + HCONTROL));
  
  	/*
  	 * First, wait for the PHYRDY change to occur before waiting for
  	 * the signature, and also verify if SStatus indicates device
  	 * presence
  	 */
97750cebb   Tejun Heo   libata: add @ap t...
806
  	temp = ata_wait_register(ap, hcr_base + HSTATUS, 0xFF, 0, 1, 500);
1bf617b71   Li Yang   ata/sata_fsl: Upd...
807
  	if ((!(temp & 0x10)) || ata_link_offline(link)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
808
809
810
  		ata_port_warn(ap, "No Device OR PHYRDY change,Hstatus = 0x%x
  ",
  			      ioread32(hcr_base + HSTATUS));
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
811
  		*class = ATA_DEV_NONE;
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
812
  		return 0;
faf0b2e5a   Li Yang   drivers/ata: add ...
813
814
815
816
817
818
  	}
  
  	/*
  	 * Wait for the first D2H from device,i.e,signature update notification
  	 */
  	start_jiffies = jiffies;
97750cebb   Tejun Heo   libata: add @ap t...
819
  	temp = ata_wait_register(ap, hcr_base + HSTATUS, 0xFF, 0x10,
faf0b2e5a   Li Yang   drivers/ata: add ...
820
821
822
  			500, jiffies_to_msecs(deadline - start_jiffies));
  
  	if ((temp & 0xFF) != 0x18) {
a9a79dfec   Joe Perches   ata: Convert ata_...
823
824
  		ata_port_warn(ap, "No Signature Update
  ");
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
825
  		*class = ATA_DEV_NONE;
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
826
  		goto do_followup_srst;
faf0b2e5a   Li Yang   drivers/ata: add ...
827
  	} else {
a9a79dfec   Joe Perches   ata: Convert ata_...
828
829
830
  		ata_port_info(ap, "Signature Update detected @ %d msecs
  ",
  			      jiffies_to_msecs(jiffies - start_jiffies));
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
  		*class = sata_fsl_dev_classify(ap);
  		return 0;
  	}
  
  do_followup_srst:
  	/*
  	 * request libATA to perform follow-up softreset
  	 */
  	return -EAGAIN;
  
  err:
  	return -EIO;
  }
  
  static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
  					unsigned long deadline)
  {
  	struct ata_port *ap = link->ap;
  	struct sata_fsl_port_priv *pp = ap->private_data;
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	int pmp = sata_srst_pmp(link);
  	u32 temp;
  	struct ata_taskfile tf;
  	u8 *cfis;
  	u32 Serror;
  
  	DPRINTK("in xx_softreset
  ");
  
  	if (ata_link_offline(link)) {
  		DPRINTK("PHY reports no device
  ");
  		*class = ATA_DEV_NONE;
  		return 0;
faf0b2e5a   Li Yang   drivers/ata: add ...
866
867
868
869
870
871
872
873
874
  	}
  
  	/*
  	 * Send a device reset (SRST) explicitly on command slot #0
  	 * Check : will the command queue (reg) be cleared during offlining ??
  	 * Also we will be online only if Phy commn. has been established
  	 * and device presence has been detected, therefore if we have
  	 * reached here, we can send a command to the target device
  	 */
faf0b2e5a   Li Yang   drivers/ata: add ...
875
876
  	DPRINTK("Sending SRST/device reset
  ");
1bf617b71   Li Yang   ata/sata_fsl: Upd...
877
  	ata_tf_init(link->device, &tf);
520d3a1a8   Li Yang   ata/sata_fsl: cle...
878
  	cfis = (u8 *) &pp->cmdentry->cfis;
faf0b2e5a   Li Yang   drivers/ata: add ...
879
880
881
  
  	/* device reset/SRST is a control register update FIS, uses tag0 */
  	sata_fsl_setup_cmd_hdr_entry(pp, 0,
d35872438   Dave Liu   sata_fsl: Fix the...
882
  		SRST_CMD | CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
faf0b2e5a   Li Yang   drivers/ata: add ...
883
884
  
  	tf.ctl |= ATA_SRST;	/* setup SRST bit in taskfile control reg */
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
885
  	ata_tf_to_fis(&tf, pmp, 0, cfis);
faf0b2e5a   Li Yang   drivers/ata: add ...
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
  
  	DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x
  ",
  		cfis[0], cfis[1], cfis[2], cfis[3]);
  
  	/*
  	 * Queue SRST command to the controller/device, ensure that no
  	 * other commands are active on the controller/device
  	 */
  
  	DPRINTK("@Softreset, CQ = 0x%x, CA = 0x%x, CC = 0x%x
  ",
  		ioread32(CQ + hcr_base),
  		ioread32(CA + hcr_base), ioread32(CC + hcr_base));
  
  	iowrite32(0xFFFF, CC + hcr_base);
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
902
903
  	if (pmp != SATA_PMP_CTRL_PORT)
  		iowrite32(pmp, CQPMP + hcr_base);
faf0b2e5a   Li Yang   drivers/ata: add ...
904
  	iowrite32(1, CQ + hcr_base);
97750cebb   Tejun Heo   libata: add @ap t...
905
  	temp = ata_wait_register(ap, CQ + hcr_base, 0x1, 0x1, 1, 5000);
faf0b2e5a   Li Yang   drivers/ata: add ...
906
  	if (temp & 0x1) {
a9a79dfec   Joe Perches   ata: Convert ata_...
907
908
  		ata_port_warn(ap, "ATA_SRST issue failed
  ");
faf0b2e5a   Li Yang   drivers/ata: add ...
909
910
911
912
913
  
  		DPRINTK("Softreset@5000,CQ=0x%x,CA=0x%x,CC=0x%x
  ",
  			ioread32(CQ + hcr_base),
  			ioread32(CA + hcr_base), ioread32(CC + hcr_base));
82ef04fb4   Tejun Heo   libata: make SCR ...
914
  		sata_fsl_scr_read(&ap->link, SCR_ERROR, &Serror);
faf0b2e5a   Li Yang   drivers/ata: add ...
915
916
917
918
919
920
921
922
923
  
  		DPRINTK("HStatus = 0x%x
  ", ioread32(hcr_base + HSTATUS));
  		DPRINTK("HControl = 0x%x
  ", ioread32(hcr_base + HCONTROL));
  		DPRINTK("Serror = 0x%x
  ", Serror);
  		goto err;
  	}
97750cebb   Tejun Heo   libata: add @ap t...
924
  	ata_msleep(ap, 1);
faf0b2e5a   Li Yang   drivers/ata: add ...
925
926
  
  	/*
25985edce   Lucas De Marchi   Fix common misspe...
927
  	 * SATA device enters reset state after receiving a Control register
faf0b2e5a   Li Yang   drivers/ata: add ...
928
929
930
931
932
  	 * FIS with SRST bit asserted and it awaits another H2D Control reg.
  	 * FIS with SRST bit cleared, then the device does internal diags &
  	 * initialization, followed by indicating it's initialization status
  	 * using ATA signature D2H register FIS to the host controller.
  	 */
d35872438   Dave Liu   sata_fsl: Fix the...
933
934
  	sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE,
  				      0, 0, 5);
faf0b2e5a   Li Yang   drivers/ata: add ...
935
936
  
  	tf.ctl &= ~ATA_SRST;	/* 2nd H2D Ctl. register FIS */
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
937
  	ata_tf_to_fis(&tf, pmp, 0, cfis);
faf0b2e5a   Li Yang   drivers/ata: add ...
938

034d8e8f2   Ashish Kalra   [libata] sata_fsl...
939
940
  	if (pmp != SATA_PMP_CTRL_PORT)
  		iowrite32(pmp, CQPMP + hcr_base);
faf0b2e5a   Li Yang   drivers/ata: add ...
941
  	iowrite32(1, CQ + hcr_base);
97750cebb   Tejun Heo   libata: add @ap t...
942
  	ata_msleep(ap, 150);		/* ?? */
faf0b2e5a   Li Yang   drivers/ata: add ...
943
944
945
946
947
948
949
  
  	/*
  	 * The above command would have signalled an interrupt on command
  	 * complete, which needs special handling, by clearing the Nth
  	 * command bit of the CCreg
  	 */
  	iowrite32(0x01, CC + hcr_base);	/* We know it will be cmd#0 always */
faf0b2e5a   Li Yang   drivers/ata: add ...
950
951
952
953
954
955
956
  
  	DPRINTK("SATA FSL : Now checking device signature
  ");
  
  	*class = ATA_DEV_NONE;
  
  	/* Verify if SStatus indicates device presence */
1bf617b71   Li Yang   ata/sata_fsl: Upd...
957
  	if (ata_link_online(link)) {
faf0b2e5a   Li Yang   drivers/ata: add ...
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
  		/*
  		 * if we are here, device presence has been detected,
  		 * 1st D2H FIS would have been received, but sfis in
  		 * command desc. is not updated, but signature register
  		 * would have been updated
  		 */
  
  		*class = sata_fsl_dev_classify(ap);
  
  		DPRINTK("class = %d
  ", *class);
  		VPRINTK("ccreg = 0x%x
  ", ioread32(hcr_base + CC));
  		VPRINTK("cereg = 0x%x
  ", ioread32(hcr_base + CE));
  	}
  
  	return 0;
  
  err:
  	return -EIO;
  }
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
980
981
982
983
984
985
986
987
  static void sata_fsl_error_handler(struct ata_port *ap)
  {
  
  	DPRINTK("in xx_error_handler
  ");
  	sata_pmp_error_handler(ap);
  
  }
faf0b2e5a   Li Yang   drivers/ata: add ...
988
989
990
991
992
993
994
995
996
997
  static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc)
  {
  	if (qc->flags & ATA_QCFLAG_FAILED)
  		qc->err_mask |= AC_ERR_OTHER;
  
  	if (qc->err_mask) {
  		/* make DMA engine forget about the failed command */
  
  	}
  }
faf0b2e5a   Li Yang   drivers/ata: add ...
998
999
  static void sata_fsl_error_intr(struct ata_port *ap)
  {
faf0b2e5a   Li Yang   drivers/ata: add ...
1000
1001
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1002
  	u32 hstatus, dereg=0, cereg = 0, SError = 0;
faf0b2e5a   Li Yang   drivers/ata: add ...
1003
  	unsigned int err_mask = 0, action = 0;
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1004
1005
1006
1007
  	int freeze = 0, abort=0;
  	struct ata_link *link = NULL;
  	struct ata_queued_cmd *qc = NULL;
  	struct ata_eh_info *ehi;
faf0b2e5a   Li Yang   drivers/ata: add ...
1008
1009
1010
  
  	hstatus = ioread32(hcr_base + HSTATUS);
  	cereg = ioread32(hcr_base + CE);
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1011
1012
1013
  	/* first, analyze and record host port events */
  	link = &ap->link;
  	ehi = &link->eh_info;
faf0b2e5a   Li Yang   drivers/ata: add ...
1014
1015
1016
1017
1018
  	ata_ehi_clear_desc(ehi);
  
  	/*
  	 * Handle & Clear SError
  	 */
82ef04fb4   Tejun Heo   libata: make SCR ...
1019
  	sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
fd6c29e3d   ashish kalra   sata_fsl: Add asy...
1020
  	if (unlikely(SError & 0xFFFF0000))
82ef04fb4   Tejun Heo   libata: make SCR ...
1021
  		sata_fsl_scr_write(&ap->link, SCR_ERROR, SError);
faf0b2e5a   Li Yang   drivers/ata: add ...
1022
1023
1024
1025
  
  	DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x
  ",
  		hstatus, cereg, ioread32(hcr_base + DE), SError);
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1026
1027
1028
1029
  	/* handle fatal errors */
  	if (hstatus & FATAL_ERROR_DECODE) {
  		ehi->err_mask |= AC_ERR_ATA_BUS;
  		ehi->action |= ATA_EH_SOFTRESET;
faf0b2e5a   Li Yang   drivers/ata: add ...
1030

faf0b2e5a   Li Yang   drivers/ata: add ...
1031
1032
  		freeze = 1;
  	}
fd6c29e3d   ashish kalra   sata_fsl: Add asy...
1033
1034
1035
  	/* Handle SDB FIS receive & notify update */
  	if (hstatus & INT_ON_SNOTIFY_UPDATE)
  		sata_async_notification(ap);
faf0b2e5a   Li Yang   drivers/ata: add ...
1036
1037
1038
1039
1040
1041
1042
  	/* Handle PHYRDY change notification */
  	if (hstatus & INT_ON_PHYRDY_CHG) {
  		DPRINTK("SATA FSL: PHYRDY change indication
  ");
  
  		/* Setup a soft-reset EH action */
  		ata_ehi_hotplugged(ehi);
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1043
  		ata_ehi_push_desc(ehi, "%s", "PHY RDY changed");
faf0b2e5a   Li Yang   drivers/ata: add ...
1044
1045
  		freeze = 1;
  	}
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
  	/* handle single device errors */
  	if (cereg) {
  		/*
  		 * clear the command error, also clears queue to the device
  		 * in error, and we can (re)issue commands to this device.
  		 * When a device is in error all commands queued into the
  		 * host controller and at the device are considered aborted
  		 * and the queue for that device is stopped. Now, after
  		 * clearing the device error, we can issue commands to the
  		 * device to interrogate it to find the source of the error.
  		 */
  		abort = 1;
  
  		DPRINTK("single device error, CE=0x%x, DE=0x%x
  ",
  			ioread32(hcr_base + CE), ioread32(hcr_base + DE));
faf0b2e5a   Li Yang   drivers/ata: add ...
1062

034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1063
1064
  		/* find out the offending link and qc */
  		if (ap->nr_pmp_links) {
4ac7534a7   Prabhakar Kushwaha   sata_fsl: Fix wro...
1065
  			unsigned int dev_num;
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1066
1067
1068
  			dereg = ioread32(hcr_base + DE);
  			iowrite32(dereg, hcr_base + DE);
  			iowrite32(cereg, hcr_base + CE);
4ac7534a7   Prabhakar Kushwaha   sata_fsl: Fix wro...
1069
1070
1071
  			dev_num = ffs(dereg) - 1;
  			if (dev_num < ap->nr_pmp_links && dereg != 0) {
  				link = &ap->pmp_link[dev_num];
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
  				ehi = &link->eh_info;
  				qc = ata_qc_from_tag(ap, link->active_tag);
  				/*
  				 * We should consider this as non fatal error,
                                   * and TF must be updated as done below.
  		                 */
  
  				err_mask |= AC_ERR_DEV;
  
  			} else {
  				err_mask |= AC_ERR_HSM;
  				action |= ATA_EH_HARDRESET;
  				freeze = 1;
  			}
  		} else {
  			dereg = ioread32(hcr_base + DE);
  			iowrite32(dereg, hcr_base + DE);
  			iowrite32(cereg, hcr_base + CE);
  
  			qc = ata_qc_from_tag(ap, link->active_tag);
  			/*
  			 * We should consider this as non fatal error,
                           * and TF must be updated as done below.
  	                */
  			err_mask |= AC_ERR_DEV;
  		}
  	}
  
  	/* record error info */
fd6c29e3d   ashish kalra   sata_fsl: Add asy...
1101
  	if (qc)
faf0b2e5a   Li Yang   drivers/ata: add ...
1102
  		qc->err_mask |= err_mask;
fd6c29e3d   ashish kalra   sata_fsl: Add asy...
1103
  	else
faf0b2e5a   Li Yang   drivers/ata: add ...
1104
1105
1106
  		ehi->err_mask |= err_mask;
  
  	ehi->action |= action;
faf0b2e5a   Li Yang   drivers/ata: add ...
1107
1108
1109
1110
  
  	/* freeze or abort */
  	if (freeze)
  		ata_port_freeze(ap);
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1111
1112
1113
1114
1115
1116
  	else if (abort) {
  		if (qc)
  			ata_link_abort(qc->dev->link);
  		else
  			ata_port_abort(ap);
  	}
faf0b2e5a   Li Yang   drivers/ata: add ...
1117
  }
faf0b2e5a   Li Yang   drivers/ata: add ...
1118
1119
1120
1121
  static void sata_fsl_host_intr(struct ata_port *ap)
  {
  	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
752e386c2   Tejun Heo   sata_fsl,mv,nv: p...
1122
  	u32 hstatus, done_mask = 0;
faf0b2e5a   Li Yang   drivers/ata: add ...
1123
1124
1125
1126
  	struct ata_queued_cmd *qc;
  	u32 SError;
  
  	hstatus = ioread32(hcr_base + HSTATUS);
82ef04fb4   Tejun Heo   libata: make SCR ...
1127
  	sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
faf0b2e5a   Li Yang   drivers/ata: add ...
1128
1129
1130
1131
1132
  
  	if (unlikely(SError & 0xFFFF0000)) {
  		DPRINTK("serror @host_intr : 0x%x
  ", SError);
  		sata_fsl_error_intr(ap);
faf0b2e5a   Li Yang   drivers/ata: add ...
1133
1134
1135
1136
1137
1138
1139
1140
  	}
  
  	if (unlikely(hstatus & INT_ON_ERROR)) {
  		DPRINTK("error interrupt!!
  ");
  		sata_fsl_error_intr(ap);
  		return;
  	}
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1141
  	/* Read command completed register */
752e386c2   Tejun Heo   sata_fsl,mv,nv: p...
1142
  	done_mask = ioread32(hcr_base + CC);
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1143
1144
1145
  
  	VPRINTK("Status of all queues :
  ");
752e386c2   Tejun Heo   sata_fsl,mv,nv: p...
1146
1147
1148
  	VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x
  ",
  		done_mask,
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1149
1150
1151
1152
  		ioread32(hcr_base + CA),
  		ioread32(hcr_base + CE),
  		ioread32(hcr_base + CQ),
  		ap->qc_active);
752e386c2   Tejun Heo   sata_fsl,mv,nv: p...
1153
  	if (done_mask & ap->qc_active) {
faf0b2e5a   Li Yang   drivers/ata: add ...
1154
  		int i;
faf0b2e5a   Li Yang   drivers/ata: add ...
1155
  		/* clear CC bit, this will also complete the interrupt */
752e386c2   Tejun Heo   sata_fsl,mv,nv: p...
1156
  		iowrite32(done_mask, hcr_base + CC);
faf0b2e5a   Li Yang   drivers/ata: add ...
1157
1158
1159
  
  		DPRINTK("Status of all queues :
  ");
752e386c2   Tejun Heo   sata_fsl,mv,nv: p...
1160
1161
1162
  		DPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x
  ",
  			done_mask, ioread32(hcr_base + CA),
faf0b2e5a   Li Yang   drivers/ata: add ...
1163
1164
1165
  			ioread32(hcr_base + CE));
  
  		for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
1aadf5c3b   Tejun Heo   libata: always us...
1166
  			if (done_mask & (1 << i))
faf0b2e5a   Li Yang   drivers/ata: add ...
1167
1168
1169
1170
1171
  				DPRINTK
  				    ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x
  ",
  				     i, ioread32(hcr_base + CC),
  				     ioread32(hcr_base + CA));
faf0b2e5a   Li Yang   drivers/ata: add ...
1172
  		}
1aadf5c3b   Tejun Heo   libata: always us...
1173
  		ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
faf0b2e5a   Li Yang   drivers/ata: add ...
1174
  		return;
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1175
  	} else if ((ap->qc_active & (1 << ATA_TAG_INTERNAL))) {
faf0b2e5a   Li Yang   drivers/ata: add ...
1176
  		iowrite32(1, hcr_base + CC);
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1177
  		qc = ata_qc_from_tag(ap, ATA_TAG_INTERNAL);
faf0b2e5a   Li Yang   drivers/ata: add ...
1178

034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1179
1180
1181
  		DPRINTK("completing non-ncq cmd, CC=0x%x
  ",
  			 ioread32(hcr_base + CC));
faf0b2e5a   Li Yang   drivers/ata: add ...
1182

034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1183
  		if (qc) {
faf0b2e5a   Li Yang   drivers/ata: add ...
1184
  			ata_qc_complete(qc);
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1185
  		}
faf0b2e5a   Li Yang   drivers/ata: add ...
1186
1187
1188
1189
1190
  	} else {
  		/* Spurious Interrupt!! */
  		DPRINTK("spurious interrupt!!, CC = 0x%x
  ",
  			ioread32(hcr_base + CC));
752e386c2   Tejun Heo   sata_fsl,mv,nv: p...
1191
  		iowrite32(done_mask, hcr_base + CC);
faf0b2e5a   Li Yang   drivers/ata: add ...
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
  		return;
  	}
  }
  
  static irqreturn_t sata_fsl_interrupt(int irq, void *dev_instance)
  {
  	struct ata_host *host = dev_instance;
  	struct sata_fsl_host_priv *host_priv = host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 interrupt_enables;
  	unsigned handled = 0;
  	struct ata_port *ap;
  
  	/* ack. any pending IRQs for this controller/port */
  	interrupt_enables = ioread32(hcr_base + HSTATUS);
  	interrupt_enables &= 0x3F;
  
  	DPRINTK("interrupt status 0x%x
  ", interrupt_enables);
  
  	if (!interrupt_enables)
  		return IRQ_NONE;
  
  	spin_lock(&host->lock);
  
  	/* Assuming one port per host controller */
  
  	ap = host->ports[0];
  	if (ap) {
  		sata_fsl_host_intr(ap);
  	} else {
a44fec1fc   Joe Perches   ata: Convert dev_...
1223
1224
  		dev_warn(host->dev, "interrupt on disabled port 0
  ");
faf0b2e5a   Li Yang   drivers/ata: add ...
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
  	}
  
  	iowrite32(interrupt_enables, hcr_base + HSTATUS);
  	handled = 1;
  
  	spin_unlock(&host->lock);
  
  	return IRQ_RETVAL(handled);
  }
  
  /*
   * Multiple ports are represented by multiple SATA controllers with
   * one port per controller
   */
  static int sata_fsl_init_controller(struct ata_host *host)
  {
  	struct sata_fsl_host_priv *host_priv = host->private_data;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	u32 temp;
  
  	/*
  	 * NOTE : We cannot bring the controller online before setting
  	 * the CHBA, hence main controller initialization is done as
  	 * part of the port_start() callback
  	 */
  
  	/* ack. any pending IRQs for this controller/port */
  	temp = ioread32(hcr_base + HSTATUS);
  	if (temp & 0x3F)
  		iowrite32((temp & 0x3F), hcr_base + HSTATUS);
  
  	/* Keep interrupts disabled on the controller */
  	temp = ioread32(hcr_base + HCONTROL);
  	iowrite32((temp & ~0x3F), hcr_base + HCONTROL);
  
  	/* Disable interrupt coalescing control(icc), for the moment */
  	DPRINTK("icc = 0x%x
  ", ioread32(hcr_base + ICC));
  	iowrite32(0x01000000, hcr_base + ICC);
  
  	/* clear error registers, SError is cleared by libATA  */
  	iowrite32(0x00000FFFF, hcr_base + CE);
  	iowrite32(0x00000FFFF, hcr_base + DE);
faf0b2e5a   Li Yang   drivers/ata: add ...
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
  	/*
  	 * host controller will be brought on-line, during xx_port_start()
  	 * callback, that should also initiate the OOB, COMINIT sequence
  	 */
  
  	DPRINTK("HStatus = 0x%x
  ", ioread32(hcr_base + HSTATUS));
  	DPRINTK("HControl = 0x%x
  ", ioread32(hcr_base + HCONTROL));
  
  	return 0;
  }
  
  /*
   * scsi mid-layer and libata interface structures
   */
  static struct scsi_host_template sata_fsl_sht = {
68d1d07b5   Tejun Heo   libata: implement...
1285
  	ATA_NCQ_SHT("sata_fsl"),
faf0b2e5a   Li Yang   drivers/ata: add ...
1286
  	.can_queue = SATA_FSL_QUEUE_DEPTH,
faf0b2e5a   Li Yang   drivers/ata: add ...
1287
  	.sg_tablesize = SATA_FSL_MAX_PRD_USABLE,
faf0b2e5a   Li Yang   drivers/ata: add ...
1288
  	.dma_boundary = ATA_DMA_BOUNDARY,
faf0b2e5a   Li Yang   drivers/ata: add ...
1289
  };
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1290
1291
  static struct ata_port_operations sata_fsl_ops = {
  	.inherits		= &sata_pmp_port_ops,
029cfd6b7   Tejun Heo   libata: implement...
1292

f90f613c3   Ashish Kalra   sata_fsl: Defer n...
1293
  	.qc_defer = ata_std_qc_defer,
faf0b2e5a   Li Yang   drivers/ata: add ...
1294
1295
  	.qc_prep = sata_fsl_qc_prep,
  	.qc_issue = sata_fsl_qc_issue,
4c9bf4e79   Tejun Heo   libata: replace t...
1296
  	.qc_fill_rtf = sata_fsl_qc_fill_rtf,
faf0b2e5a   Li Yang   drivers/ata: add ...
1297
1298
1299
1300
1301
1302
  
  	.scr_read = sata_fsl_scr_read,
  	.scr_write = sata_fsl_scr_write,
  
  	.freeze = sata_fsl_freeze,
  	.thaw = sata_fsl_thaw,
a1efdaba2   Tejun Heo   libata: make rese...
1303
  	.softreset = sata_fsl_softreset,
a0a74d1ee   Jiang Yutang   sata_fsl: Split h...
1304
  	.hardreset = sata_fsl_hardreset,
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1305
1306
  	.pmp_softreset = sata_fsl_softreset,
  	.error_handler = sata_fsl_error_handler,
faf0b2e5a   Li Yang   drivers/ata: add ...
1307
1308
1309
1310
  	.post_internal_cmd = sata_fsl_post_internal_cmd,
  
  	.port_start = sata_fsl_port_start,
  	.port_stop = sata_fsl_port_stop,
034d8e8f2   Ashish Kalra   [libata] sata_fsl...
1311
1312
1313
  
  	.pmp_attach = sata_fsl_pmp_attach,
  	.pmp_detach = sata_fsl_pmp_detach,
faf0b2e5a   Li Yang   drivers/ata: add ...
1314
1315
1316
1317
1318
  };
  
  static const struct ata_port_info sata_fsl_port_info[] = {
  	{
  	 .flags = SATA_FSL_HOST_FLAGS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
1319
1320
  	 .pio_mask = ATA_PIO4,
  	 .udma_mask = ATA_UDMA6,
faf0b2e5a   Li Yang   drivers/ata: add ...
1321
1322
1323
  	 .port_ops = &sata_fsl_ops,
  	 },
  };
1c48a5c93   Grant Likely   dt: Eliminate of_...
1324
  static int sata_fsl_probe(struct platform_device *ofdev)
faf0b2e5a   Li Yang   drivers/ata: add ...
1325
  {
e4ac522bd   Michal Sojka   sata_fsl: Return ...
1326
  	int retval = -ENXIO;
faf0b2e5a   Li Yang   drivers/ata: add ...
1327
1328
1329
1330
  	void __iomem *hcr_base = NULL;
  	void __iomem *ssr_base = NULL;
  	void __iomem *csr_base = NULL;
  	struct sata_fsl_host_priv *host_priv = NULL;
faf0b2e5a   Li Yang   drivers/ata: add ...
1331
1332
  	int irq;
  	struct ata_host *host;
578ca87c9   Prabhakar Kushwaha   sata_fsl: Update ...
1333
  	u32 temp;
faf0b2e5a   Li Yang   drivers/ata: add ...
1334
1335
1336
  
  	struct ata_port_info pi = sata_fsl_port_info[0];
  	const struct ata_port_info *ppi[] = { &pi, NULL };
a44fec1fc   Joe Perches   ata: Convert dev_...
1337
1338
  	dev_info(&ofdev->dev, "Sata FSL Platform/CSB Driver init
  ");
faf0b2e5a   Li Yang   drivers/ata: add ...
1339

61c7a080a   Grant Likely   of: Always use 's...
1340
  	hcr_base = of_iomap(ofdev->dev.of_node, 0);
faf0b2e5a   Li Yang   drivers/ata: add ...
1341
1342
1343
1344
1345
  	if (!hcr_base)
  		goto error_exit_with_cleanup;
  
  	ssr_base = hcr_base + 0x100;
  	csr_base = hcr_base + 0x140;
578ca87c9   Prabhakar Kushwaha   sata_fsl: Update ...
1346
1347
1348
1349
1350
  	if (!of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc8315-sata")) {
  		temp = ioread32(csr_base + TRANSCFG);
  		temp = temp & 0xffffffe0;
  		iowrite32(temp | TRANSCFG_RX_WATER_MARK, csr_base + TRANSCFG);
  	}
faf0b2e5a   Li Yang   drivers/ata: add ...
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
  	DPRINTK("@reset i/o = 0x%x
  ", ioread32(csr_base + TRANSCFG));
  	DPRINTK("sizeof(cmd_desc) = %d
  ", sizeof(struct command_desc));
  	DPRINTK("sizeof(#define cmd_desc) = %d
  ", SATA_FSL_CMD_DESC_SIZE);
  
  	host_priv = kzalloc(sizeof(struct sata_fsl_host_priv), GFP_KERNEL);
  	if (!host_priv)
  		goto error_exit_with_cleanup;
  
  	host_priv->hcr_base = hcr_base;
  	host_priv->ssr_base = ssr_base;
  	host_priv->csr_base = csr_base;
61c7a080a   Grant Likely   of: Always use 's...
1365
  	irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
faf0b2e5a   Li Yang   drivers/ata: add ...
1366
  	if (irq < 0) {
a44fec1fc   Joe Perches   ata: Convert dev_...
1367
1368
  		dev_err(&ofdev->dev, "invalid irq from platform
  ");
faf0b2e5a   Li Yang   drivers/ata: add ...
1369
1370
  		goto error_exit_with_cleanup;
  	}
79b3edc97   Li Yang   ata/sata_fsl: sav...
1371
  	host_priv->irq = irq;
faf0b2e5a   Li Yang   drivers/ata: add ...
1372

2f957fc95   Xulei   ATA: Add FSL sata...
1373
1374
1375
1376
  	if (of_device_is_compatible(ofdev->dev.of_node, "fsl,pq-sata-v2"))
  		host_priv->data_snoop = DATA_SNOOP_ENABLE_V2;
  	else
  		host_priv->data_snoop = DATA_SNOOP_ENABLE_V1;
faf0b2e5a   Li Yang   drivers/ata: add ...
1377
1378
1379
1380
1381
  	/* allocate host structure */
  	host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS);
  
  	/* host->iomap is not used currently */
  	host->private_data = host_priv;
faf0b2e5a   Li Yang   drivers/ata: add ...
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
  	/* initialize host controller */
  	sata_fsl_init_controller(host);
  
  	/*
  	 * Now, register with libATA core, this will also initiate the
  	 * device discovery process, invoking our port_start() handler &
  	 * error_handler() to execute a dummy Softreset EH session
  	 */
  	ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG,
  			  &sata_fsl_sht);
  
  	dev_set_drvdata(&ofdev->dev, host);
  
  	return 0;
  
  error_exit_with_cleanup:
  
  	if (hcr_base)
  		iounmap(hcr_base);
  	if (host_priv)
  		kfree(host_priv);
  
  	return retval;
  }
2dc115813   Grant Likely   of/device: Replac...
1406
  static int sata_fsl_remove(struct platform_device *ofdev)
faf0b2e5a   Li Yang   drivers/ata: add ...
1407
1408
1409
1410
1411
1412
1413
  {
  	struct ata_host *host = dev_get_drvdata(&ofdev->dev);
  	struct sata_fsl_host_priv *host_priv = host->private_data;
  
  	ata_host_detach(host);
  
  	dev_set_drvdata(&ofdev->dev, NULL);
79b3edc97   Li Yang   ata/sata_fsl: sav...
1414
  	irq_dispose_mapping(host_priv->irq);
faf0b2e5a   Li Yang   drivers/ata: add ...
1415
1416
1417
1418
1419
  	iounmap(host_priv->hcr_base);
  	kfree(host_priv);
  
  	return 0;
  }
dc77ad4c8   Dave Liu   sata_fsl: Add pow...
1420
  #ifdef CONFIG_PM
2dc115813   Grant Likely   of/device: Replac...
1421
  static int sata_fsl_suspend(struct platform_device *op, pm_message_t state)
dc77ad4c8   Dave Liu   sata_fsl: Add pow...
1422
1423
1424
1425
  {
  	struct ata_host *host = dev_get_drvdata(&op->dev);
  	return ata_host_suspend(host, state);
  }
2dc115813   Grant Likely   of/device: Replac...
1426
  static int sata_fsl_resume(struct platform_device *op)
dc77ad4c8   Dave Liu   sata_fsl: Add pow...
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
  {
  	struct ata_host *host = dev_get_drvdata(&op->dev);
  	struct sata_fsl_host_priv *host_priv = host->private_data;
  	int ret;
  	void __iomem *hcr_base = host_priv->hcr_base;
  	struct ata_port *ap = host->ports[0];
  	struct sata_fsl_port_priv *pp = ap->private_data;
  
  	ret = sata_fsl_init_controller(host);
  	if (ret) {
a44fec1fc   Joe Perches   ata: Convert dev_...
1437
1438
  		dev_err(&op->dev, "Error initializing hardware
  ");
dc77ad4c8   Dave Liu   sata_fsl: Add pow...
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
  		return ret;
  	}
  
  	/* Recovery the CHBA register in host controller cmd register set */
  	iowrite32(pp->cmdslot_paddr & 0xffffffff, hcr_base + CHBA);
  
  	ata_host_resume(host);
  	return 0;
  }
  #endif
faf0b2e5a   Li Yang   drivers/ata: add ...
1449
1450
  static struct of_device_id fsl_sata_match[] = {
  	{
96ce1b6dc   Kim Phillips   [POWERPC] sata_fs...
1451
  		.compatible = "fsl,pq-sata",
faf0b2e5a   Li Yang   drivers/ata: add ...
1452
  	},
2f957fc95   Xulei   ATA: Add FSL sata...
1453
1454
1455
  	{
  		.compatible = "fsl,pq-sata-v2",
  	},
faf0b2e5a   Li Yang   drivers/ata: add ...
1456
1457
1458
1459
  	{},
  };
  
  MODULE_DEVICE_TABLE(of, fsl_sata_match);
1c48a5c93   Grant Likely   dt: Eliminate of_...
1460
  static struct platform_driver fsl_sata_driver = {
4018294b5   Grant Likely   of: Remove duplic...
1461
1462
1463
1464
1465
  	.driver = {
  		.name = "fsl-sata",
  		.owner = THIS_MODULE,
  		.of_match_table = fsl_sata_match,
  	},
faf0b2e5a   Li Yang   drivers/ata: add ...
1466
1467
  	.probe		= sata_fsl_probe,
  	.remove		= sata_fsl_remove,
dc77ad4c8   Dave Liu   sata_fsl: Add pow...
1468
1469
1470
1471
  #ifdef CONFIG_PM
  	.suspend	= sata_fsl_suspend,
  	.resume		= sata_fsl_resume,
  #endif
faf0b2e5a   Li Yang   drivers/ata: add ...
1472
  };
99c8ea3e5   Axel Lin   SATA/PATA: conver...
1473
  module_platform_driver(fsl_sata_driver);
faf0b2e5a   Li Yang   drivers/ata: add ...
1474
1475
1476
1477
1478
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Ashish Kalra, Freescale Semiconductor");
  MODULE_DESCRIPTION("Freescale 3.0Gbps SATA controller low level driver");
  MODULE_VERSION("1.10");