Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[linux-2.6-block.git] / drivers / scsi / mvsas / mv_94xx.c
1 /*
2  * Marvell 88SE94xx hardware specific
3  *
4  * Copyright 2007 Red Hat, Inc.
5  * Copyright 2008 Marvell. <kewei@marvell.com>
6  * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
7  *
8  * This file is licensed under GPLv2.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; version 2 of the
13  * License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23  * USA
24 */
25
26 #include "mv_sas.h"
27 #include "mv_94xx.h"
28 #include "mv_chips.h"
29
30 static void mvs_94xx_detect_porttype(struct mvs_info *mvi, int i)
31 {
32         u32 reg;
33         struct mvs_phy *phy = &mvi->phy[i];
34         u32 phy_status;
35
36         mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE3);
37         reg = mvs_read_port_vsr_data(mvi, i);
38         phy_status = ((reg & 0x3f0000) >> 16) & 0xff;
39         phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
40         switch (phy_status) {
41         case 0x10:
42                 phy->phy_type |= PORT_TYPE_SAS;
43                 break;
44         case 0x1d:
45         default:
46                 phy->phy_type |= PORT_TYPE_SATA;
47                 break;
48         }
49 }
50
51 static void __devinit mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id)
52 {
53         void __iomem *regs = mvi->regs;
54         u32 tmp;
55
56         tmp = mr32(MVS_PCS);
57         tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT2);
58         mw32(MVS_PCS, tmp);
59 }
60
61 static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
62 {
63         u32 tmp;
64
65         tmp = mvs_read_port_irq_stat(mvi, phy_id);
66         tmp &= ~PHYEV_RDY_CH;
67         mvs_write_port_irq_stat(mvi, phy_id, tmp);
68         if (hard) {
69                 tmp = mvs_read_phy_ctl(mvi, phy_id);
70                 tmp |= PHY_RST_HARD;
71                 mvs_write_phy_ctl(mvi, phy_id, tmp);
72                 do {
73                         tmp = mvs_read_phy_ctl(mvi, phy_id);
74                 } while (tmp & PHY_RST_HARD);
75         } else {
76                 mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_STAT);
77                 tmp = mvs_read_port_vsr_data(mvi, phy_id);
78                 tmp |= PHY_RST;
79                 mvs_write_port_vsr_data(mvi, phy_id, tmp);
80         }
81 }
82
83 static void mvs_94xx_phy_disable(struct mvs_info *mvi, u32 phy_id)
84 {
85         u32 tmp;
86         mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
87         tmp = mvs_read_port_vsr_data(mvi, phy_id);
88         mvs_write_port_vsr_data(mvi, phy_id, tmp | 0x00800000);
89 }
90
91 static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id)
92 {
93         mvs_write_port_vsr_addr(mvi, phy_id, 0x1B4);
94         mvs_write_port_vsr_data(mvi, phy_id, 0x8300ffc1);
95         mvs_write_port_vsr_addr(mvi, phy_id, 0x104);
96         mvs_write_port_vsr_data(mvi, phy_id, 0x00018080);
97         mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
98         mvs_write_port_vsr_data(mvi, phy_id, 0x00207fff);
99 }
100
101 static int __devinit mvs_94xx_init(struct mvs_info *mvi)
102 {
103         void __iomem *regs = mvi->regs;
104         int i;
105         u32 tmp, cctl;
106
107         mvs_show_pcie_usage(mvi);
108         if (mvi->flags & MVF_FLAG_SOC) {
109                 tmp = mr32(MVS_PHY_CTL);
110                 tmp &= ~PCTL_PWR_OFF;
111                 tmp |= PCTL_PHY_DSBL;
112                 mw32(MVS_PHY_CTL, tmp);
113         }
114
115         /* Init Chip */
116         /* make sure RST is set; HBA_RST /should/ have done that for us */
117         cctl = mr32(MVS_CTL) & 0xFFFF;
118         if (cctl & CCTL_RST)
119                 cctl &= ~CCTL_RST;
120         else
121                 mw32_f(MVS_CTL, cctl | CCTL_RST);
122
123         if (mvi->flags & MVF_FLAG_SOC) {
124                 tmp = mr32(MVS_PHY_CTL);
125                 tmp &= ~PCTL_PWR_OFF;
126                 tmp |= PCTL_COM_ON;
127                 tmp &= ~PCTL_PHY_DSBL;
128                 tmp |= PCTL_LINK_RST;
129                 mw32(MVS_PHY_CTL, tmp);
130                 msleep(100);
131                 tmp &= ~PCTL_LINK_RST;
132                 mw32(MVS_PHY_CTL, tmp);
133                 msleep(100);
134         }
135
136         /* reset control */
137         mw32(MVS_PCS, 0);               /* MVS_PCS */
138         mw32(MVS_STP_REG_SET_0, 0);
139         mw32(MVS_STP_REG_SET_1, 0);
140
141         /* init phys */
142         mvs_phy_hacks(mvi);
143
144         /* disable Multiplexing, enable phy implemented */
145         mw32(MVS_PORTS_IMP, 0xFF);
146
147
148         mw32(MVS_PA_VSR_ADDR, 0x00000104);
149         mw32(MVS_PA_VSR_PORT, 0x00018080);
150         mw32(MVS_PA_VSR_ADDR, VSR_PHY_MODE8);
151         mw32(MVS_PA_VSR_PORT, 0x0084ffff);
152
153         /* set LED blink when IO*/
154         mw32(MVS_PA_VSR_ADDR, 0x00000030);
155         tmp = mr32(MVS_PA_VSR_PORT);
156         tmp &= 0xFFFF00FF;
157         tmp |= 0x00003300;
158         mw32(MVS_PA_VSR_PORT, tmp);
159
160         mw32(MVS_CMD_LIST_LO, mvi->slot_dma);
161         mw32(MVS_CMD_LIST_HI, (mvi->slot_dma >> 16) >> 16);
162
163         mw32(MVS_RX_FIS_LO, mvi->rx_fis_dma);
164         mw32(MVS_RX_FIS_HI, (mvi->rx_fis_dma >> 16) >> 16);
165
166         mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ);
167         mw32(MVS_TX_LO, mvi->tx_dma);
168         mw32(MVS_TX_HI, (mvi->tx_dma >> 16) >> 16);
169
170         mw32(MVS_RX_CFG, MVS_RX_RING_SZ);
171         mw32(MVS_RX_LO, mvi->rx_dma);
172         mw32(MVS_RX_HI, (mvi->rx_dma >> 16) >> 16);
173
174         for (i = 0; i < mvi->chip->n_phy; i++) {
175                 mvs_94xx_phy_disable(mvi, i);
176                 /* set phy local SAS address */
177                 mvs_set_sas_addr(mvi, i, CONFIG_ID_FRAME3, CONFIG_ID_FRAME4,
178                                                 (mvi->phy[i].dev_sas_addr));
179
180                 mvs_94xx_enable_xmt(mvi, i);
181                 mvs_94xx_phy_enable(mvi, i);
182
183                 mvs_94xx_phy_reset(mvi, i, 1);
184                 msleep(500);
185                 mvs_94xx_detect_porttype(mvi, i);
186         }
187
188         if (mvi->flags & MVF_FLAG_SOC) {
189                 /* set select registers */
190                 writel(0x0E008000, regs + 0x000);
191                 writel(0x59000008, regs + 0x004);
192                 writel(0x20, regs + 0x008);
193                 writel(0x20, regs + 0x00c);
194                 writel(0x20, regs + 0x010);
195                 writel(0x20, regs + 0x014);
196                 writel(0x20, regs + 0x018);
197                 writel(0x20, regs + 0x01c);
198         }
199         for (i = 0; i < mvi->chip->n_phy; i++) {
200                 /* clear phy int status */
201                 tmp = mvs_read_port_irq_stat(mvi, i);
202                 tmp &= ~PHYEV_SIG_FIS;
203                 mvs_write_port_irq_stat(mvi, i, tmp);
204
205                 /* set phy int mask */
206                 tmp = PHYEV_RDY_CH | PHYEV_BROAD_CH |
207                         PHYEV_ID_DONE  | PHYEV_DCDR_ERR | PHYEV_CRC_ERR ;
208                 mvs_write_port_irq_mask(mvi, i, tmp);
209
210                 msleep(100);
211                 mvs_update_phyinfo(mvi, i, 1);
212         }
213
214         /* FIXME: update wide port bitmaps */
215
216         /* little endian for open address and command table, etc. */
217         /*
218          * it seems that ( from the spec ) turning on big-endian won't
219          * do us any good on big-endian machines, need further confirmation
220          */
221         cctl = mr32(MVS_CTL);
222         cctl |= CCTL_ENDIAN_CMD;
223         cctl |= CCTL_ENDIAN_DATA;
224         cctl &= ~CCTL_ENDIAN_OPEN;
225         cctl |= CCTL_ENDIAN_RSP;
226         mw32_f(MVS_CTL, cctl);
227
228         /* reset CMD queue */
229         tmp = mr32(MVS_PCS);
230         tmp |= PCS_CMD_RST;
231         mw32(MVS_PCS, tmp);
232         /* interrupt coalescing may cause missing HW interrput in some case,
233          * and the max count is 0x1ff, while our max slot is 0x200,
234          * it will make count 0.
235          */
236         tmp = 0;
237         mw32(MVS_INT_COAL, tmp);
238
239         tmp = 0x100;
240         mw32(MVS_INT_COAL_TMOUT, tmp);
241
242         /* ladies and gentlemen, start your engines */
243         mw32(MVS_TX_CFG, 0);
244         mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ | TX_EN);
245         mw32(MVS_RX_CFG, MVS_RX_RING_SZ | RX_EN);
246         /* enable CMD/CMPL_Q/RESP mode */
247         mw32(MVS_PCS, PCS_SATA_RETRY_2 | PCS_FIS_RX_EN |
248                 PCS_CMD_EN | PCS_CMD_STOP_ERR);
249
250         /* enable completion queue interrupt */
251         tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP |
252                 CINT_DMA_PCIE);
253         tmp |= CINT_PHY_MASK;
254         mw32(MVS_INT_MASK, tmp);
255
256         /* Enable SRS interrupt */
257         mw32(MVS_INT_MASK_SRS_0, 0xFFFF);
258
259         return 0;
260 }
261
262 static int mvs_94xx_ioremap(struct mvs_info *mvi)
263 {
264         if (!mvs_ioremap(mvi, 2, -1)) {
265                 mvi->regs_ex = mvi->regs + 0x10200;
266                 mvi->regs += 0x20000;
267                 if (mvi->id == 1)
268                         mvi->regs += 0x4000;
269                 return 0;
270         }
271         return -1;
272 }
273
274 static void mvs_94xx_iounmap(struct mvs_info *mvi)
275 {
276         if (mvi->regs) {
277                 mvi->regs -= 0x20000;
278                 if (mvi->id == 1)
279                         mvi->regs -= 0x4000;
280                 mvs_iounmap(mvi->regs);
281         }
282 }
283
284 static void mvs_94xx_interrupt_enable(struct mvs_info *mvi)
285 {
286         void __iomem *regs = mvi->regs_ex;
287         u32 tmp;
288
289         tmp = mr32(MVS_GBL_CTL);
290         tmp |= (IRQ_SAS_A | IRQ_SAS_B);
291         mw32(MVS_GBL_INT_STAT, tmp);
292         writel(tmp, regs + 0x0C);
293         writel(tmp, regs + 0x10);
294         writel(tmp, regs + 0x14);
295         writel(tmp, regs + 0x18);
296         mw32(MVS_GBL_CTL, tmp);
297 }
298
299 static void mvs_94xx_interrupt_disable(struct mvs_info *mvi)
300 {
301         void __iomem *regs = mvi->regs_ex;
302         u32 tmp;
303
304         tmp = mr32(MVS_GBL_CTL);
305
306         tmp &= ~(IRQ_SAS_A | IRQ_SAS_B);
307         mw32(MVS_GBL_INT_STAT, tmp);
308         writel(tmp, regs + 0x0C);
309         writel(tmp, regs + 0x10);
310         writel(tmp, regs + 0x14);
311         writel(tmp, regs + 0x18);
312         mw32(MVS_GBL_CTL, tmp);
313 }
314
315 static u32 mvs_94xx_isr_status(struct mvs_info *mvi, int irq)
316 {
317         void __iomem *regs = mvi->regs_ex;
318         u32 stat = 0;
319         if (!(mvi->flags & MVF_FLAG_SOC)) {
320                 stat = mr32(MVS_GBL_INT_STAT);
321
322                 if (!(stat & (IRQ_SAS_A | IRQ_SAS_B)))
323                         return 0;
324         }
325         return stat;
326 }
327
328 static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat)
329 {
330         void __iomem *regs = mvi->regs;
331
332         if (((stat & IRQ_SAS_A) && mvi->id == 0) ||
333                         ((stat & IRQ_SAS_B) && mvi->id == 1)) {
334                 mw32_f(MVS_INT_STAT, CINT_DONE);
335         #ifndef MVS_USE_TASKLET
336                 spin_lock(&mvi->lock);
337         #endif
338                 mvs_int_full(mvi);
339         #ifndef MVS_USE_TASKLET
340                 spin_unlock(&mvi->lock);
341         #endif
342         }
343         return IRQ_HANDLED;
344 }
345
346 static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx)
347 {
348         u32 tmp;
349         mvs_cw32(mvi, 0x300 + (slot_idx >> 3), 1 << (slot_idx % 32));
350         do {
351                 tmp = mvs_cr32(mvi, 0x300 + (slot_idx >> 3));
352         } while (tmp & 1 << (slot_idx % 32));
353 }
354
355 static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type,
356                                 u32 tfs)
357 {
358         void __iomem *regs = mvi->regs;
359         u32 tmp;
360
361         if (type == PORT_TYPE_SATA) {
362                 tmp = mr32(MVS_INT_STAT_SRS_0) | (1U << tfs);
363                 mw32(MVS_INT_STAT_SRS_0, tmp);
364         }
365         mw32(MVS_INT_STAT, CINT_CI_STOP);
366         tmp = mr32(MVS_PCS) | 0xFF00;
367         mw32(MVS_PCS, tmp);
368 }
369
370 static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)
371 {
372         void __iomem *regs = mvi->regs;
373         u32 tmp;
374         u8 reg_set = *tfs;
375
376         if (*tfs == MVS_ID_NOT_MAPPED)
377                 return;
378
379         mvi->sata_reg_set &= ~bit(reg_set);
380         if (reg_set < 32) {
381                 w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set);
382                 tmp = mr32(MVS_INT_STAT_SRS_0) & (u32)mvi->sata_reg_set;
383                 if (tmp)
384                         mw32(MVS_INT_STAT_SRS_0, tmp);
385         } else {
386                 w_reg_set_enable(reg_set, mvi->sata_reg_set);
387                 tmp = mr32(MVS_INT_STAT_SRS_1) & mvi->sata_reg_set;
388                 if (tmp)
389                         mw32(MVS_INT_STAT_SRS_1, tmp);
390         }
391
392         *tfs = MVS_ID_NOT_MAPPED;
393
394         return;
395 }
396
397 static u8 mvs_94xx_assign_reg_set(struct mvs_info *mvi, u8 *tfs)
398 {
399         int i;
400         void __iomem *regs = mvi->regs;
401
402         if (*tfs != MVS_ID_NOT_MAPPED)
403                 return 0;
404
405         i = mv_ffc64(mvi->sata_reg_set);
406         if (i > 32) {
407                 mvi->sata_reg_set |= bit(i);
408                 w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32));
409                 *tfs = i;
410                 return 0;
411         } else if (i >= 0) {
412                 mvi->sata_reg_set |= bit(i);
413                 w_reg_set_enable(i, (u32)mvi->sata_reg_set);
414                 *tfs = i;
415                 return 0;
416         }
417         return MVS_ID_NOT_MAPPED;
418 }
419
420 static void mvs_94xx_make_prd(struct scatterlist *scatter, int nr, void *prd)
421 {
422         int i;
423         struct scatterlist *sg;
424         struct mvs_prd *buf_prd = prd;
425         for_each_sg(scatter, sg, nr, i) {
426                 buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
427                 buf_prd->im_len.len = cpu_to_le32(sg_dma_len(sg));
428                 buf_prd++;
429         }
430 }
431
432 static int mvs_94xx_oob_done(struct mvs_info *mvi, int i)
433 {
434         u32 phy_st;
435         phy_st = mvs_read_phy_ctl(mvi, i);
436         if (phy_st & PHY_READY_MASK)    /* phy ready */
437                 return 1;
438         return 0;
439 }
440
441 static void mvs_94xx_get_dev_identify_frame(struct mvs_info *mvi, int port_id,
442                                         struct sas_identify_frame *id)
443 {
444         int i;
445         u32 id_frame[7];
446
447         for (i = 0; i < 7; i++) {
448                 mvs_write_port_cfg_addr(mvi, port_id,
449                                         CONFIG_ID_FRAME0 + i * 4);
450                 id_frame[i] = mvs_read_port_cfg_data(mvi, port_id);
451         }
452         memcpy(id, id_frame, 28);
453 }
454
455 static void mvs_94xx_get_att_identify_frame(struct mvs_info *mvi, int port_id,
456                                         struct sas_identify_frame *id)
457 {
458         int i;
459         u32 id_frame[7];
460
461         /* mvs_hexdump(28, (u8 *)id_frame, 0); */
462         for (i = 0; i < 7; i++) {
463                 mvs_write_port_cfg_addr(mvi, port_id,
464                                         CONFIG_ATT_ID_FRAME0 + i * 4);
465                 id_frame[i] = mvs_read_port_cfg_data(mvi, port_id);
466                 mv_dprintk("94xx phy %d atta frame %d %x.\n",
467                         port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]);
468         }
469         /* mvs_hexdump(28, (u8 *)id_frame, 0); */
470         memcpy(id, id_frame, 28);
471 }
472
473 static u32 mvs_94xx_make_dev_info(struct sas_identify_frame *id)
474 {
475         u32 att_dev_info = 0;
476
477         att_dev_info |= id->dev_type;
478         if (id->stp_iport)
479                 att_dev_info |= PORT_DEV_STP_INIT;
480         if (id->smp_iport)
481                 att_dev_info |= PORT_DEV_SMP_INIT;
482         if (id->ssp_iport)
483                 att_dev_info |= PORT_DEV_SSP_INIT;
484         if (id->stp_tport)
485                 att_dev_info |= PORT_DEV_STP_TRGT;
486         if (id->smp_tport)
487                 att_dev_info |= PORT_DEV_SMP_TRGT;
488         if (id->ssp_tport)
489                 att_dev_info |= PORT_DEV_SSP_TRGT;
490
491         att_dev_info |= (u32)id->phy_id<<24;
492         return att_dev_info;
493 }
494
495 static u32 mvs_94xx_make_att_info(struct sas_identify_frame *id)
496 {
497         return mvs_94xx_make_dev_info(id);
498 }
499
500 static void mvs_94xx_fix_phy_info(struct mvs_info *mvi, int i,
501                                 struct sas_identify_frame *id)
502 {
503         struct mvs_phy *phy = &mvi->phy[i];
504         struct asd_sas_phy *sas_phy = &phy->sas_phy;
505         mv_dprintk("get all reg link rate is 0x%x\n", phy->phy_status);
506         sas_phy->linkrate =
507                 (phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
508                         PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET;
509         sas_phy->linkrate += 0x8;
510         mv_dprintk("get link rate is %d\n", sas_phy->linkrate);
511         phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
512         phy->maximum_linkrate = SAS_LINK_RATE_6_0_GBPS;
513         mvs_94xx_get_dev_identify_frame(mvi, i, id);
514         phy->dev_info = mvs_94xx_make_dev_info(id);
515
516         if (phy->phy_type & PORT_TYPE_SAS) {
517                 mvs_94xx_get_att_identify_frame(mvi, i, id);
518                 phy->att_dev_info = mvs_94xx_make_att_info(id);
519                 phy->att_dev_sas_addr = *(u64 *)id->sas_addr;
520         } else {
521                 phy->att_dev_info = PORT_DEV_STP_TRGT | 1;
522         }
523
524 }
525
526 void mvs_94xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id,
527                         struct sas_phy_linkrates *rates)
528 {
529         /* TODO */
530 }
531
532 static void mvs_94xx_clear_active_cmds(struct mvs_info *mvi)
533 {
534         u32 tmp;
535         void __iomem *regs = mvi->regs;
536         tmp = mr32(MVS_STP_REG_SET_0);
537         mw32(MVS_STP_REG_SET_0, 0);
538         mw32(MVS_STP_REG_SET_0, tmp);
539         tmp = mr32(MVS_STP_REG_SET_1);
540         mw32(MVS_STP_REG_SET_1, 0);
541         mw32(MVS_STP_REG_SET_1, tmp);
542 }
543
544
545 u32 mvs_94xx_spi_read_data(struct mvs_info *mvi)
546 {
547         void __iomem *regs = mvi->regs_ex - 0x10200;
548         return mr32(SPI_RD_DATA_REG_94XX);
549 }
550
551 void mvs_94xx_spi_write_data(struct mvs_info *mvi, u32 data)
552 {
553         void __iomem *regs = mvi->regs_ex - 0x10200;
554          mw32(SPI_RD_DATA_REG_94XX, data);
555 }
556
557
558 int mvs_94xx_spi_buildcmd(struct mvs_info *mvi,
559                                 u32      *dwCmd,
560                                 u8       cmd,
561                                 u8       read,
562                                 u8       length,
563                                 u32      addr
564                                 )
565 {
566         void __iomem *regs = mvi->regs_ex - 0x10200;
567         u32  dwTmp;
568
569         dwTmp = ((u32)cmd << 8) | ((u32)length << 4);
570         if (read)
571                 dwTmp |= SPI_CTRL_READ_94XX;
572
573         if (addr != MV_MAX_U32) {
574                 mw32(SPI_ADDR_REG_94XX, (addr & 0x0003FFFFL));
575                 dwTmp |= SPI_ADDR_VLD_94XX;
576         }
577
578         *dwCmd = dwTmp;
579         return 0;
580 }
581
582
583 int mvs_94xx_spi_issuecmd(struct mvs_info *mvi, u32 cmd)
584 {
585         void __iomem *regs = mvi->regs_ex - 0x10200;
586         mw32(SPI_CTRL_REG_94XX, cmd | SPI_CTRL_SpiStart_94XX);
587
588         return 0;
589 }
590
591 int mvs_94xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout)
592 {
593         void __iomem *regs = mvi->regs_ex - 0x10200;
594         u32   i, dwTmp;
595
596         for (i = 0; i < timeout; i++) {
597                 dwTmp = mr32(SPI_CTRL_REG_94XX);
598                 if (!(dwTmp & SPI_CTRL_SpiStart_94XX))
599                         return 0;
600                 msleep(10);
601         }
602
603         return -1;
604 }
605
606 #ifndef DISABLE_HOTPLUG_DMA_FIX
607 void mvs_94xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd)
608 {
609         int i;
610         struct mvs_prd *buf_prd = prd;
611         buf_prd += from;
612         for (i = 0; i < MAX_SG_ENTRY - from; i++) {
613                 buf_prd->addr = cpu_to_le64(buf_dma);
614                 buf_prd->im_len.len = cpu_to_le32(buf_len);
615                 ++buf_prd;
616         }
617 }
618 #endif
619
620 /*
621  * FIXME JEJB: temporary nop clear_srs_irq to make 94xx still work
622  * with 64xx fixes
623  */
624 static void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set,
625                                    u8 clear_all)
626 {
627 }
628
629 const struct mvs_dispatch mvs_94xx_dispatch = {
630         "mv94xx",
631         mvs_94xx_init,
632         NULL,
633         mvs_94xx_ioremap,
634         mvs_94xx_iounmap,
635         mvs_94xx_isr,
636         mvs_94xx_isr_status,
637         mvs_94xx_interrupt_enable,
638         mvs_94xx_interrupt_disable,
639         mvs_read_phy_ctl,
640         mvs_write_phy_ctl,
641         mvs_read_port_cfg_data,
642         mvs_write_port_cfg_data,
643         mvs_write_port_cfg_addr,
644         mvs_read_port_vsr_data,
645         mvs_write_port_vsr_data,
646         mvs_write_port_vsr_addr,
647         mvs_read_port_irq_stat,
648         mvs_write_port_irq_stat,
649         mvs_read_port_irq_mask,
650         mvs_write_port_irq_mask,
651         mvs_get_sas_addr,
652         mvs_94xx_command_active,
653         mvs_94xx_clear_srs_irq,
654         mvs_94xx_issue_stop,
655         mvs_start_delivery,
656         mvs_rx_update,
657         mvs_int_full,
658         mvs_94xx_assign_reg_set,
659         mvs_94xx_free_reg_set,
660         mvs_get_prd_size,
661         mvs_get_prd_count,
662         mvs_94xx_make_prd,
663         mvs_94xx_detect_porttype,
664         mvs_94xx_oob_done,
665         mvs_94xx_fix_phy_info,
666         NULL,
667         mvs_94xx_phy_set_link_rate,
668         mvs_hw_max_link_rate,
669         mvs_94xx_phy_disable,
670         mvs_94xx_phy_enable,
671         mvs_94xx_phy_reset,
672         NULL,
673         mvs_94xx_clear_active_cmds,
674         mvs_94xx_spi_read_data,
675         mvs_94xx_spi_write_data,
676         mvs_94xx_spi_buildcmd,
677         mvs_94xx_spi_issuecmd,
678         mvs_94xx_spi_waitdataready,
679 #ifndef DISABLE_HOTPLUG_DMA_FIX
680         mvs_94xx_fix_dma,
681 #endif
682 };
683