summaryrefslogtreecommitdiff
path: root/drivers/rapidio/devices/tsi721.h
blob: 957eadc5815095045f06291dbc2b83bbaea795d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
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
133
134
135
136
137
138
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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
227
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
289
290
291
292
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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
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
377
378
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
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
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
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
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
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
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
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
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
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
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
/*
 * Tsi721 PCIExpress-to-SRIO bridge definitions
 *
 * Copyright 2011, Integrated Device Technology, Inc.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#ifndef __TSI721_H
#define __TSI721_H

/* Debug output filtering masks */
enum {
	DBG_NONE	= 0,
	DBG_INIT	= BIT(0), /* driver init */
	DBG_EXIT	= BIT(1), /* driver exit */
	DBG_MPORT	= BIT(2), /* mport add/remove */
	DBG_MAINT	= BIT(3), /* maintenance ops messages */
	DBG_DMA		= BIT(4), /* DMA transfer messages */
	DBG_DMAV	= BIT(5), /* verbose DMA transfer messages */
	DBG_IBW		= BIT(6), /* inbound window */
	DBG_EVENT	= BIT(7), /* event handling messages */
	DBG_OBW		= BIT(8), /* outbound window messages */
	DBG_DBELL	= BIT(9), /* doorbell messages */
	DBG_OMSG	= BIT(10), /* doorbell messages */
	DBG_IMSG	= BIT(11), /* doorbell messages */
	DBG_ALL		= ~0,
};

#ifdef DEBUG
extern u32 tsi_dbg_level;

#define tsi_debug(level, dev, fmt, arg...)				\
	do {								\
		if (DBG_##level & tsi_dbg_level)				\
			dev_dbg(dev, "%s: " fmt "\n", __func__, ##arg);	\
	} while (0)
#else
#define tsi_debug(level, dev, fmt, arg...) \
		no_printk(KERN_DEBUG "%s: " fmt "\n", __func__, ##arg)
#endif

#define tsi_info(dev, fmt, arg...) \
	dev_info(dev, "%s: " fmt "\n", __func__, ##arg)

#define tsi_warn(dev, fmt, arg...) \
	dev_warn(dev, "%s: WARNING " fmt "\n", __func__, ##arg)

#define tsi_err(dev, fmt, arg...) \
	dev_err(dev, "%s: ERROR " fmt "\n", __func__, ##arg)

#define DRV_NAME	"tsi721"

#define DEFAULT_HOPCOUNT	0xff
#define DEFAULT_DESTID		0xff

/* PCI device ID */
#define PCI_DEVICE_ID_TSI721		0x80ab

#define BAR_0	0
#define BAR_1	1
#define BAR_2	2
#define BAR_4	4

#define TSI721_PC2SR_BARS	2
#define TSI721_PC2SR_WINS	8
#define TSI721_PC2SR_ZONES	8
#define TSI721_MAINT_WIN	0 /* Window for outbound maintenance requests */
#define IDB_QUEUE		0 /* Inbound Doorbell Queue to use */
#define IDB_QSIZE		512 /* Inbound Doorbell Queue size */

/* Memory space sizes */
#define TSI721_REG_SPACE_SIZE		(512 * 1024) /* 512K */
#define TSI721_DB_WIN_SIZE		(16 * 1024 * 1024) /* 16MB */

#define  RIO_TT_CODE_8		0x00000000
#define  RIO_TT_CODE_16		0x00000001

#define TSI721_DMA_MAXCH	8
#define TSI721_DMA_MINSTSSZ	32
#define TSI721_DMA_STSBLKSZ	8

#define TSI721_SRIO_MAXCH	8

#define DBELL_SID(buf)		(((u8)buf[2] << 8) | (u8)buf[3])
#define DBELL_TID(buf)		(((u8)buf[4] << 8) | (u8)buf[5])
#define DBELL_INF(buf)		(((u8)buf[0] << 8) | (u8)buf[1])

#define TSI721_RIO_PW_MSG_SIZE	16  /* Tsi721 saves only 16 bytes of PW msg */

/* Register definitions */

/*
 * Registers in PCIe configuration space
 */

#define TSI721_PCIECFG_MSIXTBL	0x0a4
#define TSI721_MSIXTBL_OFFSET	0x2c000
#define TSI721_PCIECFG_MSIXPBA	0x0a8
#define TSI721_MSIXPBA_OFFSET	0x2a000
#define TSI721_PCIECFG_EPCTL	0x400

/*
 * Event Management Registers
 */

#define TSI721_RIO_EM_INT_STAT		0x10910
#define TSI721_RIO_EM_INT_STAT_PW_RX	0x00010000

#define TSI721_RIO_EM_INT_ENABLE	0x10914
#define TSI721_RIO_EM_INT_ENABLE_PW_RX	0x00010000

#define TSI721_RIO_EM_DEV_INT_EN	0x10930
#define TSI721_RIO_EM_DEV_INT_EN_INT	0x00000001

/*
 * Port-Write Block Registers
 */

#define TSI721_RIO_PW_CTL		0x10a04
#define TSI721_RIO_PW_CTL_PW_TIMER	0xf0000000
#define TSI721_RIO_PW_CTL_PWT_DIS	(0 << 28)
#define TSI721_RIO_PW_CTL_PWT_103	(1 << 28)
#define TSI721_RIO_PW_CTL_PWT_205	(1 << 29)
#define TSI721_RIO_PW_CTL_PWT_410	(1 << 30)
#define TSI721_RIO_PW_CTL_PWT_820	(1 << 31)
#define TSI721_RIO_PW_CTL_PWC_MODE	0x01000000
#define TSI721_RIO_PW_CTL_PWC_CONT	0x00000000
#define TSI721_RIO_PW_CTL_PWC_REL	0x01000000

#define TSI721_RIO_PW_RX_STAT		0x10a10
#define TSI721_RIO_PW_RX_STAT_WR_SIZE	0x0000f000
#define TSI_RIO_PW_RX_STAT_WDPTR	0x00000100
#define TSI721_RIO_PW_RX_STAT_PW_SHORT	0x00000008
#define TSI721_RIO_PW_RX_STAT_PW_TRUNC	0x00000004
#define TSI721_RIO_PW_RX_STAT_PW_DISC	0x00000002
#define TSI721_RIO_PW_RX_STAT_PW_VAL	0x00000001

#define TSI721_RIO_PW_RX_CAPT(x)	(0x10a20 + (x)*4)

/*
 * Inbound Doorbells
 */

#define TSI721_IDB_ENTRY_SIZE	64

#define TSI721_IDQ_CTL(x)	(0x20000 + (x) * 0x1000)
#define TSI721_IDQ_SUSPEND	0x00000002
#define TSI721_IDQ_INIT		0x00000001

#define TSI721_IDQ_STS(x)	(0x20004 + (x) * 0x1000)
#define TSI721_IDQ_RUN		0x00200000

#define TSI721_IDQ_MASK(x)	(0x20008 + (x) * 0x1000)
#define TSI721_IDQ_MASK_MASK	0xffff0000
#define TSI721_IDQ_MASK_PATT	0x0000ffff

#define TSI721_IDQ_RP(x)	(0x2000c + (x) * 0x1000)
#define TSI721_IDQ_RP_PTR	0x0007ffff

#define TSI721_IDQ_WP(x)	(0x20010 + (x) * 0x1000)
#define TSI721_IDQ_WP_PTR	0x0007ffff

#define TSI721_IDQ_BASEL(x)	(0x20014 + (x) * 0x1000)
#define TSI721_IDQ_BASEL_ADDR	0xffffffc0
#define TSI721_IDQ_BASEU(x)	(0x20018 + (x) * 0x1000)
#define TSI721_IDQ_SIZE(x)	(0x2001c + (x) * 0x1000)
#define TSI721_IDQ_SIZE_VAL(size)	(__fls(size) - 4)
#define TSI721_IDQ_SIZE_MIN	512
#define TSI721_IDQ_SIZE_MAX	(512 * 1024)

#define TSI721_SR_CHINT(x)	(0x20040 + (x) * 0x1000)
#define TSI721_SR_CHINTE(x)	(0x20044 + (x) * 0x1000)
#define TSI721_SR_CHINTSET(x)	(0x20048 + (x) * 0x1000)
#define TSI721_SR_CHINT_ODBOK	0x00000020
#define TSI721_SR_CHINT_IDBQRCV	0x00000010
#define TSI721_SR_CHINT_SUSP	0x00000008
#define TSI721_SR_CHINT_ODBTO	0x00000004
#define TSI721_SR_CHINT_ODBRTRY	0x00000002
#define TSI721_SR_CHINT_ODBERR	0x00000001
#define TSI721_SR_CHINT_ALL	0x0000003f

#define TSI721_IBWIN_NUM	8

#define TSI721_IBWIN_LB(x)	(0x29000 + (x) * 0x20)
#define TSI721_IBWIN_LB_BA	0xfffff000
#define TSI721_IBWIN_LB_WEN	0x00000001

#define TSI721_IBWIN_UB(x)	(0x29004 + (x) * 0x20)
#define TSI721_IBWIN_SZ(x)	(0x29008 + (x) * 0x20)
#define TSI721_IBWIN_SZ_SIZE	0x00001f00
#define TSI721_IBWIN_SIZE(size)	(__fls(size) - 12)

#define TSI721_IBWIN_TLA(x)	(0x2900c + (x) * 0x20)
#define TSI721_IBWIN_TLA_ADD	0xfffff000
#define TSI721_IBWIN_TUA(x)	(0x29010 + (x) * 0x20)

#define TSI721_SR2PC_GEN_INTE	0x29800
#define TSI721_SR2PC_PWE	0x29804
#define TSI721_SR2PC_GEN_INT	0x29808

#define TSI721_DEV_INTE		0x29840
#define TSI721_DEV_INT		0x29844
#define TSI721_DEV_INTSET	0x29848
#define TSI721_DEV_INT_BDMA_CH	0x00002000
#define TSI721_DEV_INT_BDMA_NCH	0x00001000
#define TSI721_DEV_INT_SMSG_CH	0x00000800
#define TSI721_DEV_INT_SMSG_NCH	0x00000400
#define TSI721_DEV_INT_SR2PC_CH	0x00000200
#define TSI721_DEV_INT_SRIO	0x00000020

#define TSI721_DEV_CHAN_INTE	0x2984c
#define TSI721_DEV_CHAN_INT	0x29850

#define TSI721_INT_SR2PC_CHAN_M	0xff000000
#define TSI721_INT_SR2PC_CHAN(x) (1 << (24 + (x)))
#define TSI721_INT_IMSG_CHAN_M	0x00ff0000
#define TSI721_INT_IMSG_CHAN(x)	(1 << (16 + (x)))
#define TSI721_INT_OMSG_CHAN_M	0x0000ff00
#define TSI721_INT_OMSG_CHAN(x)	(1 << (8 + (x)))
#define TSI721_INT_BDMA_CHAN_M	0x000000ff
#define TSI721_INT_BDMA_CHAN(x)	(1 << (x))

/*
 * PC2SR block registers
 */
#define TSI721_OBWIN_NUM	TSI721_PC2SR_WINS

#define TSI721_OBWINLB(x)	(0x40000 + (x) * 0x20)
#define TSI721_OBWINLB_BA	0xffff8000
#define TSI721_OBWINLB_WEN	0x00000001

#define TSI721_OBWINUB(x)	(0x40004 + (x) * 0x20)

#define TSI721_OBWINSZ(x)	(0x40008 + (x) * 0x20)
#define TSI721_OBWINSZ_SIZE	0x00001f00
#define TSI721_OBWIN_SIZE(size)	(__fls(size) - 15)

#define TSI721_ZONE_SEL		0x41300
#define TSI721_ZONE_SEL_RD_WRB	0x00020000
#define TSI721_ZONE_SEL_GO	0x00010000
#define TSI721_ZONE_SEL_WIN	0x00000038
#define TSI721_ZONE_SEL_ZONE	0x00000007

#define TSI721_LUT_DATA0	0x41304
#define TSI721_LUT_DATA0_ADD	0xfffff000
#define TSI721_LUT_DATA0_RDTYPE	0x00000f00
#define TSI721_LUT_DATA0_NREAD	0x00000100
#define TSI721_LUT_DATA0_MNTRD	0x00000200
#define TSI721_LUT_DATA0_RDCRF	0x00000020
#define TSI721_LUT_DATA0_WRCRF	0x00000010
#define TSI721_LUT_DATA0_WRTYPE	0x0000000f
#define TSI721_LUT_DATA0_NWR	0x00000001
#define TSI721_LUT_DATA0_MNTWR	0x00000002
#define TSI721_LUT_DATA0_NWR_R	0x00000004

#define TSI721_LUT_DATA1	0x41308

#define TSI721_LUT_DATA2	0x4130c
#define TSI721_LUT_DATA2_HC	0xff000000
#define TSI721_LUT_DATA2_ADD65	0x000c0000
#define TSI721_LUT_DATA2_TT	0x00030000
#define TSI721_LUT_DATA2_DSTID	0x0000ffff

#define TSI721_PC2SR_INTE	0x41310

#define TSI721_DEVCTL		0x48004
#define TSI721_DEVCTL_SRBOOT_CMPL	0x00000004

#define TSI721_I2C_INT_ENABLE	0x49120

/*
 * Block DMA Engine Registers
 *   x = 0..7
 */

#define TSI721_DMAC_BASE(x)	(0x51000 + (x) * 0x1000)

#define TSI721_DMAC_DWRCNT	0x000
#define TSI721_DMAC_DRDCNT	0x004

#define TSI721_DMAC_CTL		0x008
#define TSI721_DMAC_CTL_SUSP	0x00000002
#define TSI721_DMAC_CTL_INIT	0x00000001

#define TSI721_DMAC_INT		0x00c
#define TSI721_DMAC_INT_STFULL	0x00000010
#define TSI721_DMAC_INT_DONE	0x00000008
#define TSI721_DMAC_INT_SUSP	0x00000004
#define TSI721_DMAC_INT_ERR	0x00000002
#define TSI721_DMAC_INT_IOFDONE	0x00000001
#define TSI721_DMAC_INT_ALL	0x0000001f

#define TSI721_DMAC_INTSET	0x010

#define TSI721_DMAC_STS		0x014
#define TSI721_DMAC_STS_ABORT	0x00400000
#define TSI721_DMAC_STS_RUN	0x00200000
#define TSI721_DMAC_STS_CS	0x001f0000

#define TSI721_DMAC_INTE	0x018

#define TSI721_DMAC_DPTRL	0x024
#define TSI721_DMAC_DPTRL_MASK	0xffffffe0

#define TSI721_DMAC_DPTRH	0x028

#define TSI721_DMAC_DSBL	0x02c
#define TSI721_DMAC_DSBL_MASK	0xffffffc0

#define TSI721_DMAC_DSBH	0x030

#define TSI721_DMAC_DSSZ	0x034
#define TSI721_DMAC_DSSZ_SIZE_M	0x0000000f
#define TSI721_DMAC_DSSZ_SIZE(size)	(__fls(size) - 4)

#define TSI721_DMAC_DSRP	0x038
#define TSI721_DMAC_DSRP_MASK	0x0007ffff

#define TSI721_DMAC_DSWP	0x03c
#define TSI721_DMAC_DSWP_MASK	0x0007ffff

#define TSI721_BDMA_INTE	0x5f000

/*
 * Messaging definitions
 */
#define TSI721_MSG_BUFFER_SIZE		RIO_MAX_MSG_SIZE
#define TSI721_MSG_MAX_SIZE		RIO_MAX_MSG_SIZE
#define TSI721_IMSG_MAXCH		8
#define TSI721_IMSG_CHNUM		TSI721_IMSG_MAXCH
#define TSI721_IMSGD_MIN_RING_SIZE	32
#define TSI721_IMSGD_RING_SIZE		512

#define TSI721_OMSG_CHNUM		4 /* One channel per MBOX */
#define TSI721_OMSGD_MIN_RING_SIZE	32
#define TSI721_OMSGD_RING_SIZE		512

/*
 * Outbound Messaging Engine Registers
 *   x = 0..7
 */

#define TSI721_OBDMAC_DWRCNT(x)		(0x61000 + (x) * 0x1000)

#define TSI721_OBDMAC_DRDCNT(x)		(0x61004 + (x) * 0x1000)

#define TSI721_OBDMAC_CTL(x)		(0x61008 + (x) * 0x1000)
#define TSI721_OBDMAC_CTL_MASK		0x00000007
#define TSI721_OBDMAC_CTL_RETRY_THR	0x00000004
#define TSI721_OBDMAC_CTL_SUSPEND	0x00000002
#define TSI721_OBDMAC_CTL_INIT		0x00000001

#define TSI721_OBDMAC_INT(x)		(0x6100c + (x) * 0x1000)
#define TSI721_OBDMAC_INTSET(x)		(0x61010 + (x) * 0x1000)
#define TSI721_OBDMAC_INTE(x)		(0x61018 + (x) * 0x1000)
#define TSI721_OBDMAC_INT_MASK		0x0000001F
#define TSI721_OBDMAC_INT_ST_FULL	0x00000010
#define TSI721_OBDMAC_INT_DONE		0x00000008
#define TSI721_OBDMAC_INT_SUSPENDED	0x00000004
#define TSI721_OBDMAC_INT_ERROR		0x00000002
#define TSI721_OBDMAC_INT_IOF_DONE	0x00000001
#define TSI721_OBDMAC_INT_ALL		TSI721_OBDMAC_INT_MASK

#define TSI721_OBDMAC_STS(x)		(0x61014 + (x) * 0x1000)
#define TSI721_OBDMAC_STS_MASK		0x007f0000
#define TSI721_OBDMAC_STS_ABORT		0x00400000
#define TSI721_OBDMAC_STS_RUN		0x00200000
#define TSI721_OBDMAC_STS_CS		0x001f0000

#define TSI721_OBDMAC_PWE(x)		(0x6101c + (x) * 0x1000)
#define TSI721_OBDMAC_PWE_MASK		0x00000002
#define TSI721_OBDMAC_PWE_ERROR_EN	0x00000002

#define TSI721_OBDMAC_DPTRL(x)		(0x61020 + (x) * 0x1000)
#define TSI721_OBDMAC_DPTRL_MASK	0xfffffff0

#define TSI721_OBDMAC_DPTRH(x)		(0x61024 + (x) * 0x1000)
#define TSI721_OBDMAC_DPTRH_MASK	0xffffffff

#define TSI721_OBDMAC_DSBL(x)		(0x61040 + (x) * 0x1000)
#define TSI721_OBDMAC_DSBL_MASK		0xffffffc0

#define TSI721_OBDMAC_DSBH(x)		(0x61044 + (x) * 0x1000)
#define TSI721_OBDMAC_DSBH_MASK		0xffffffff

#define TSI721_OBDMAC_DSSZ(x)		(0x61048 + (x) * 0x1000)
#define TSI721_OBDMAC_DSSZ_MASK		0x0000000f

#define TSI721_OBDMAC_DSRP(x)		(0x6104c + (x) * 0x1000)
#define TSI721_OBDMAC_DSRP_MASK		0x0007ffff

#define TSI721_OBDMAC_DSWP(x)		(0x61050 + (x) * 0x1000)
#define TSI721_OBDMAC_DSWP_MASK		0x0007ffff

#define TSI721_RQRPTO			0x60010
#define TSI721_RQRPTO_MASK		0x00ffffff
#define TSI721_RQRPTO_VAL		400	/* Response TO value */

/*
 * Inbound Messaging Engine Registers
 *   x = 0..7
 */

#define TSI721_IB_DEVID_GLOBAL		0xffff
#define TSI721_IBDMAC_FQBL(x)		(0x61200 + (x) * 0x1000)
#define TSI721_IBDMAC_FQBL_MASK		0xffffffc0

#define TSI721_IBDMAC_FQBH(x)		(0x61204 + (x) * 0x1000)
#define TSI721_IBDMAC_FQBH_MASK		0xffffffff

#define TSI721_IBDMAC_FQSZ_ENTRY_INX	TSI721_IMSGD_RING_SIZE
#define TSI721_IBDMAC_FQSZ(x)		(0x61208 + (x) * 0x1000)
#define TSI721_IBDMAC_FQSZ_MASK		0x0000000f

#define TSI721_IBDMAC_FQRP(x)		(0x6120c + (x) * 0x1000)
#define TSI721_IBDMAC_FQRP_MASK		0x0007ffff

#define TSI721_IBDMAC_FQWP(x)		(0x61210 + (x) * 0x1000)
#define TSI721_IBDMAC_FQWP_MASK		0x0007ffff

#define TSI721_IBDMAC_FQTH(x)		(0x61214 + (x) * 0x1000)
#define TSI721_IBDMAC_FQTH_MASK		0x0007ffff

#define TSI721_IB_DEVID			0x60020
#define TSI721_IB_DEVID_MASK		0x0000ffff

#define TSI721_IBDMAC_CTL(x)		(0x61240 + (x) * 0x1000)
#define TSI721_IBDMAC_CTL_MASK		0x00000003
#define TSI721_IBDMAC_CTL_SUSPEND	0x00000002
#define TSI721_IBDMAC_CTL_INIT		0x00000001

#define TSI721_IBDMAC_STS(x)		(0x61244 + (x) * 0x1000)
#define TSI721_IBDMAC_STS_MASK		0x007f0000
#define TSI721_IBSMAC_STS_ABORT		0x00400000
#define TSI721_IBSMAC_STS_RUN		0x00200000
#define TSI721_IBSMAC_STS_CS		0x001f0000

#define TSI721_IBDMAC_INT(x)		(0x61248 + (x) * 0x1000)
#define TSI721_IBDMAC_INTSET(x)		(0x6124c + (x) * 0x1000)
#define TSI721_IBDMAC_INTE(x)		(0x61250 + (x) * 0x1000)
#define TSI721_IBDMAC_INT_MASK		0x0000100f
#define TSI721_IBDMAC_INT_SRTO		0x00001000
#define TSI721_IBDMAC_INT_SUSPENDED	0x00000008
#define TSI721_IBDMAC_INT_PC_ERROR	0x00000004
#define TSI721_IBDMAC_INT_FQ_LOW	0x00000002
#define TSI721_IBDMAC_INT_DQ_RCV	0x00000001
#define TSI721_IBDMAC_INT_ALL		TSI721_IBDMAC_INT_MASK

#define TSI721_IBDMAC_PWE(x)		(0x61254 + (x) * 0x1000)
#define TSI721_IBDMAC_PWE_MASK		0x00001700
#define TSI721_IBDMAC_PWE_SRTO		0x00001000
#define TSI721_IBDMAC_PWE_ILL_FMT	0x00000400
#define TSI721_IBDMAC_PWE_ILL_DEC	0x00000200
#define TSI721_IBDMAC_PWE_IMP_SP	0x00000100

#define TSI721_IBDMAC_DQBL(x)		(0x61300 + (x) * 0x1000)
#define TSI721_IBDMAC_DQBL_MASK		0xffffffc0
#define TSI721_IBDMAC_DQBL_ADDR		0xffffffc0

#define TSI721_IBDMAC_DQBH(x)		(0x61304 + (x) * 0x1000)
#define TSI721_IBDMAC_DQBH_MASK		0xffffffff

#define TSI721_IBDMAC_DQRP(x)		(0x61308 + (x) * 0x1000)
#define TSI721_IBDMAC_DQRP_MASK		0x0007ffff

#define TSI721_IBDMAC_DQWR(x)		(0x6130c + (x) * 0x1000)
#define TSI721_IBDMAC_DQWR_MASK		0x0007ffff

#define TSI721_IBDMAC_DQSZ(x)		(0x61314 + (x) * 0x1000)
#define TSI721_IBDMAC_DQSZ_MASK		0x0000000f

/*
 * Messaging Engine Interrupts
 */

#define TSI721_SMSG_PWE			0x6a004

#define TSI721_SMSG_INTE		0x6a000
#define TSI721_SMSG_INT			0x6a008
#define TSI721_SMSG_INTSET		0x6a010
#define TSI721_SMSG_INT_MASK		0x0086ffff
#define TSI721_SMSG_INT_UNS_RSP		0x00800000
#define TSI721_SMSG_INT_ECC_NCOR	0x00040000
#define TSI721_SMSG_INT_ECC_COR		0x00020000
#define TSI721_SMSG_INT_ECC_NCOR_CH	0x0000ff00
#define TSI721_SMSG_INT_ECC_COR_CH	0x000000ff

#define TSI721_SMSG_ECC_LOG		0x6a014
#define TSI721_SMSG_ECC_LOG_MASK	0x00070007
#define TSI721_SMSG_ECC_LOG_ECC_NCOR_M	0x00070000
#define TSI721_SMSG_ECC_LOG_ECC_COR_M	0x00000007

#define TSI721_RETRY_GEN_CNT		0x6a100
#define TSI721_RETRY_GEN_CNT_MASK	0xffffffff

#define TSI721_RETRY_RX_CNT		0x6a104
#define TSI721_RETRY_RX_CNT_MASK	0xffffffff

#define TSI721_SMSG_ECC_COR_LOG(x)	(0x6a300 + (x) * 4)
#define TSI721_SMSG_ECC_COR_LOG_MASK	0x000000ff

#define TSI721_SMSG_ECC_NCOR(x)		(0x6a340 + (x) * 4)
#define TSI721_SMSG_ECC_NCOR_MASK	0x000000ff

/*
 * Block DMA Descriptors
 */

struct tsi721_dma_desc {
	__le32 type_id;

#define TSI721_DMAD_DEVID	0x0000ffff
#define TSI721_DMAD_CRF		0x00010000
#define TSI721_DMAD_PRIO	0x00060000
#define TSI721_DMAD_RTYPE	0x00780000
#define TSI721_DMAD_IOF		0x08000000
#define TSI721_DMAD_DTYPE	0xe0000000

	__le32 bcount;

#define TSI721_DMAD_BCOUNT1	0x03ffffff /* if DTYPE == 1 */
#define TSI721_DMAD_BCOUNT2	0x0000000f /* if DTYPE == 2 */
#define TSI721_DMAD_TT		0x0c000000
#define TSI721_DMAD_RADDR0	0xc0000000

	union {
		__le32 raddr_lo;	   /* if DTYPE == (1 || 2) */
		__le32 next_lo;		   /* if DTYPE == 3 */
	};

#define TSI721_DMAD_CFGOFF	0x00ffffff
#define TSI721_DMAD_HOPCNT	0xff000000

	union {
		__le32 raddr_hi;	   /* if DTYPE == (1 || 2) */
		__le32 next_hi;		   /* if DTYPE == 3 */
	};

	union {
		struct {		   /* if DTYPE == 1 */
			__le32 bufptr_lo;
			__le32 bufptr_hi;
			__le32 s_dist;
			__le32 s_size;
		} t1;
		__le32 data[4];		   /* if DTYPE == 2 */
		u32    reserved[4];	   /* if DTYPE == 3 */
	};
} __aligned(32);

/*
 * Inbound Messaging Descriptor
 */
struct tsi721_imsg_desc {
	__le32 type_id;

#define TSI721_IMD_DEVID	0x0000ffff
#define TSI721_IMD_CRF		0x00010000
#define TSI721_IMD_PRIO		0x00060000
#define TSI721_IMD_TT		0x00180000
#define TSI721_IMD_DTYPE	0xe0000000

	__le32 msg_info;

#define TSI721_IMD_BCOUNT	0x00000ff8
#define TSI721_IMD_SSIZE	0x0000f000
#define TSI721_IMD_LETER	0x00030000
#define TSI721_IMD_XMBOX	0x003c0000
#define TSI721_IMD_MBOX		0x00c00000
#define TSI721_IMD_CS		0x78000000
#define TSI721_IMD_HO		0x80000000

	__le32 bufptr_lo;
	__le32 bufptr_hi;
	u32    reserved[12];

} __aligned(64);

/*
 * Outbound Messaging Descriptor
 */
struct tsi721_omsg_desc {
	__le32 type_id;

#define TSI721_OMD_DEVID	0x0000ffff
#define TSI721_OMD_CRF		0x00010000
#define TSI721_OMD_PRIO		0x00060000
#define TSI721_OMD_IOF		0x08000000
#define TSI721_OMD_DTYPE	0xe0000000
#define TSI721_OMD_RSRVD	0x17f80000

	__le32 msg_info;

#define TSI721_OMD_BCOUNT	0x00000ff8
#define TSI721_OMD_SSIZE	0x0000f000
#define TSI721_OMD_LETER	0x00030000
#define TSI721_OMD_XMBOX	0x003c0000
#define TSI721_OMD_MBOX		0x00c00000
#define TSI721_OMD_TT		0x0c000000

	union {
		__le32 bufptr_lo;	/* if DTYPE == 4 */
		__le32 next_lo;		/* if DTYPE == 5 */
	};

	union {
		__le32 bufptr_hi;	/* if DTYPE == 4 */
		__le32 next_hi;		/* if DTYPE == 5 */
	};

} __aligned(16);

struct tsi721_dma_sts {
	__le64	desc_sts[8];
} __aligned(64);

struct tsi721_desc_sts_fifo {
	union {
		__le64	da64;
		struct {
			__le32	lo;
			__le32	hi;
		} da32;
	} stat[8];
} __aligned(64);

/* Descriptor types for BDMA and Messaging blocks */
enum dma_dtype {
	DTYPE1 = 1, /* Data Transfer DMA Descriptor */
	DTYPE2 = 2, /* Immediate Data Transfer DMA Descriptor */
	DTYPE3 = 3, /* Block Pointer DMA Descriptor */
	DTYPE4 = 4, /* Outbound Msg DMA Descriptor */
	DTYPE5 = 5, /* OB Messaging Block Pointer Descriptor */
	DTYPE6 = 6  /* Inbound Messaging Descriptor */
};

enum dma_rtype {
	NREAD = 0,
	LAST_NWRITE_R = 1,
	ALL_NWRITE = 2,
	ALL_NWRITE_R = 3,
	MAINT_RD = 4,
	MAINT_WR = 5
};

/*
 * mport Driver Definitions
 */
#define TSI721_DMA_CHNUM	TSI721_DMA_MAXCH

#define TSI721_DMACH_MAINT	7	/* DMA channel for maint requests */
#define TSI721_DMACH_MAINT_NBD	32	/* Number of BDs for maint requests */

#define TSI721_DMACH_DMA	1	/* DMA channel for data transfers */

#define MSG_DMA_ENTRY_INX_TO_SIZE(x)	((0x10 << (x)) & 0xFFFF0)

enum tsi721_smsg_int_flag {
	SMSG_INT_NONE		= 0x00000000,
	SMSG_INT_ECC_COR_CH	= 0x000000ff,
	SMSG_INT_ECC_NCOR_CH	= 0x0000ff00,
	SMSG_INT_ECC_COR	= 0x00020000,
	SMSG_INT_ECC_NCOR	= 0x00040000,
	SMSG_INT_UNS_RSP	= 0x00800000,
	SMSG_INT_ALL		= 0x0006ffff
};

/* Structures */

#ifdef CONFIG_RAPIDIO_DMA_ENGINE

#define TSI721_BDMA_MAX_BCOUNT	(TSI721_DMAD_BCOUNT1 + 1)

struct tsi721_tx_desc {
	struct dma_async_tx_descriptor	txd;
	u16				destid;
	/* low 64-bits of 66-bit RIO address */
	u64				rio_addr;
	/* upper 2-bits of 66-bit RIO address */
	u8				rio_addr_u;
	enum dma_rtype			rtype;
	struct list_head		desc_node;
	struct scatterlist		*sg;
	unsigned int			sg_len;
	enum dma_status			status;
};

struct tsi721_bdma_chan {
	int		id;
	void __iomem	*regs;
	int		bd_num;		/* number of HW buffer descriptors */
	void		*bd_base;	/* start of DMA descriptors */
	dma_addr_t	bd_phys;
	void		*sts_base;	/* start of DMA BD status FIFO */
	dma_addr_t	sts_phys;
	int		sts_size;
	u32		sts_rdptr;
	u32		wr_count;
	u32		wr_count_next;

	struct dma_chan		dchan;
	struct tsi721_tx_desc	*tx_desc;
	spinlock_t		lock;
	struct tsi721_tx_desc	*active_tx;
	struct list_head	queue;
	struct list_head	free_list;
	struct tasklet_struct	tasklet;
	bool			active;
};

#endif /* CONFIG_RAPIDIO_DMA_ENGINE */

struct tsi721_bdma_maint {
	int		ch_id;		/* BDMA channel number */
	int		bd_num;		/* number of buffer descriptors */
	void		*bd_base;	/* start of DMA descriptors */
	dma_addr_t	bd_phys;
	void		*sts_base;	/* start of DMA BD status FIFO */
	dma_addr_t	sts_phys;
	int		sts_size;
};

struct tsi721_imsg_ring {
	u32		size;
	/* VA/PA of data buffers for incoming messages */
	void		*buf_base;
	dma_addr_t	buf_phys;
	/* VA/PA of circular free buffer list */
	void		*imfq_base;
	dma_addr_t	imfq_phys;
	/* VA/PA of Inbound message descriptors */
	void		*imd_base;
	dma_addr_t	imd_phys;
	 /* Inbound Queue buffer pointers */
	void		*imq_base[TSI721_IMSGD_RING_SIZE];

	u32		rx_slot;
	void		*dev_id;
	u32		fq_wrptr;
	u32		desc_rdptr;
	spinlock_t	lock;
};

struct tsi721_omsg_ring {
	u32		size;
	/* VA/PA of OB Msg descriptors */
	void		*omd_base;
	dma_addr_t	omd_phys;
	/* VA/PA of OB Msg data buffers */
	void		*omq_base[TSI721_OMSGD_RING_SIZE];
	dma_addr_t	omq_phys[TSI721_OMSGD_RING_SIZE];
	/* VA/PA of OB Msg descriptor status FIFO */
	void		*sts_base;
	dma_addr_t	sts_phys;
	u32		sts_size; /* # of allocated status entries */
	u32		sts_rdptr;

	u32		tx_slot;
	void		*dev_id;
	u32		wr_count;
	spinlock_t	lock;
};

enum tsi721_flags {
	TSI721_USING_MSI	= (1 << 0),
	TSI721_USING_MSIX	= (1 << 1),
	TSI721_IMSGID_SET	= (1 << 2),
};

#ifdef CONFIG_PCI_MSI
/*
 * MSI-X Table Entries (0 ... 69)
 */
#define TSI721_MSIX_DMACH_DONE(x)	(0 + (x))
#define TSI721_MSIX_DMACH_INT(x)	(8 + (x))
#define TSI721_MSIX_BDMA_INT		16
#define TSI721_MSIX_OMSG_DONE(x)	(17 + (x))
#define TSI721_MSIX_OMSG_INT(x)		(25 + (x))
#define TSI721_MSIX_IMSG_DQ_RCV(x)	(33 + (x))
#define TSI721_MSIX_IMSG_INT(x)		(41 + (x))
#define TSI721_MSIX_MSG_INT		49
#define TSI721_MSIX_SR2PC_IDBQ_RCV(x)	(50 + (x))
#define TSI721_MSIX_SR2PC_CH_INT(x)	(58 + (x))
#define TSI721_MSIX_SR2PC_INT		66
#define TSI721_MSIX_PC2SR_INT		67
#define TSI721_MSIX_SRIO_MAC_INT	68
#define TSI721_MSIX_I2C_INT		69

/* MSI-X vector and init table entry indexes */
enum tsi721_msix_vect {
	TSI721_VECT_IDB,
	TSI721_VECT_PWRX, /* PW_RX is part of SRIO MAC Interrupt reporting */
	TSI721_VECT_OMB0_DONE,
	TSI721_VECT_OMB1_DONE,
	TSI721_VECT_OMB2_DONE,
	TSI721_VECT_OMB3_DONE,
	TSI721_VECT_OMB0_INT,
	TSI721_VECT_OMB1_INT,
	TSI721_VECT_OMB2_INT,
	TSI721_VECT_OMB3_INT,
	TSI721_VECT_IMB0_RCV,
	TSI721_VECT_IMB1_RCV,
	TSI721_VECT_IMB2_RCV,
	TSI721_VECT_IMB3_RCV,
	TSI721_VECT_IMB0_INT,
	TSI721_VECT_IMB1_INT,
	TSI721_VECT_IMB2_INT,
	TSI721_VECT_IMB3_INT,
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
	TSI721_VECT_DMA0_DONE,
	TSI721_VECT_DMA1_DONE,
	TSI721_VECT_DMA2_DONE,
	TSI721_VECT_DMA3_DONE,
	TSI721_VECT_DMA4_DONE,
	TSI721_VECT_DMA5_DONE,
	TSI721_VECT_DMA6_DONE,
	TSI721_VECT_DMA7_DONE,
	TSI721_VECT_DMA0_INT,
	TSI721_VECT_DMA1_INT,
	TSI721_VECT_DMA2_INT,
	TSI721_VECT_DMA3_INT,
	TSI721_VECT_DMA4_INT,
	TSI721_VECT_DMA5_INT,
	TSI721_VECT_DMA6_INT,
	TSI721_VECT_DMA7_INT,
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
	TSI721_VECT_MAX
};

#define IRQ_DEVICE_NAME_MAX	64

struct msix_irq {
	u16	vector;
	char	irq_name[IRQ_DEVICE_NAME_MAX];
};
#endif /* CONFIG_PCI_MSI */

struct tsi721_ib_win_mapping {
	struct list_head node;
	dma_addr_t	lstart;
};

struct tsi721_ib_win {
	u64		rstart;
	u32		size;
	dma_addr_t	lstart;
	bool		active;
	bool		xlat;
	struct list_head mappings;
};

struct tsi721_obw_bar {
	u64		base;
	u64		size;
	u64		free;
};

struct tsi721_ob_win {
	u64		base;
	u32		size;
	u16		destid;
	u64		rstart;
	bool		active;
	struct tsi721_obw_bar *pbar;
};

struct tsi721_device {
	struct pci_dev	*pdev;
	struct rio_mport mport;
	u32		flags;
	void __iomem	*regs;
#ifdef CONFIG_PCI_MSI
	struct msix_irq	msix[TSI721_VECT_MAX];
#endif
	/* Doorbells */
	void __iomem	*odb_base;
	void		*idb_base;
	dma_addr_t	idb_dma;
	struct work_struct idb_work;
	u32		db_discard_count;

	/* Inbound Port-Write */
	struct work_struct pw_work;
	struct kfifo	pw_fifo;
	spinlock_t	pw_fifo_lock;
	u32		pw_discard_count;

	/* BDMA Engine */
	struct tsi721_bdma_maint mdma; /* Maintenance rd/wr request channel */

#ifdef CONFIG_RAPIDIO_DMA_ENGINE
	struct tsi721_bdma_chan bdma[TSI721_DMA_CHNUM];
#endif

	/* Inbound Messaging */
	int		imsg_init[TSI721_IMSG_CHNUM];
	struct tsi721_imsg_ring imsg_ring[TSI721_IMSG_CHNUM];

	/* Outbound Messaging */
	int		omsg_init[TSI721_OMSG_CHNUM];
	struct tsi721_omsg_ring	omsg_ring[TSI721_OMSG_CHNUM];

	/* Inbound Mapping Windows */
	struct tsi721_ib_win ib_win[TSI721_IBWIN_NUM];
	int		ibwin_cnt;

	/* Outbound Mapping Windows */
	struct tsi721_obw_bar p2r_bar[2];
	struct tsi721_ob_win  ob_win[TSI721_OBWIN_NUM];
	int		obwin_cnt;
};

#ifdef CONFIG_RAPIDIO_DMA_ENGINE
extern void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan);
extern int tsi721_register_dma(struct tsi721_device *priv);
extern void tsi721_unregister_dma(struct tsi721_device *priv);
extern void tsi721_dma_stop_all(struct tsi721_device *priv);
#else
#define tsi721_dma_stop_all(priv) do {} while (0)
#define tsi721_unregister_dma(priv) do {} while (0)
#endif

#endif