2 * IDT CPS RapidIO switches support
4 * Copyright 2009-2010 Integrated Device Technology, Inc.
5 * Alexandre Bounine <alexandre.bounine@idt.com>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
13 #include <linux/rio.h>
14 #include <linux/rio_drv.h>
15 #include <linux/rio_ids.h>
16 #include <linux/module.h>
19 #define CPS_DEFAULT_ROUTE 0xde
20 #define CPS_NO_ROUTE 0xdf
22 #define IDTCPS_RIO_DOMAIN 0xf20020
25 idtcps_route_add_entry(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
26 u16 table
, u16 route_destid
, u8 route_port
)
30 if (route_port
== RIO_INVALID_ROUTE
)
31 route_port
= CPS_DEFAULT_ROUTE
;
33 if (table
== RIO_GLOBAL_TABLE
) {
34 rio_mport_write_config_32(mport
, destid
, hopcount
,
35 RIO_STD_RTE_CONF_DESTID_SEL_CSR
, route_destid
);
37 rio_mport_read_config_32(mport
, destid
, hopcount
,
38 RIO_STD_RTE_CONF_PORT_SEL_CSR
, &result
);
40 result
= (0xffffff00 & result
) | (u32
)route_port
;
41 rio_mport_write_config_32(mport
, destid
, hopcount
,
42 RIO_STD_RTE_CONF_PORT_SEL_CSR
, result
);
49 idtcps_route_get_entry(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
50 u16 table
, u16 route_destid
, u8
*route_port
)
54 if (table
== RIO_GLOBAL_TABLE
) {
55 rio_mport_write_config_32(mport
, destid
, hopcount
,
56 RIO_STD_RTE_CONF_DESTID_SEL_CSR
, route_destid
);
58 rio_mport_read_config_32(mport
, destid
, hopcount
,
59 RIO_STD_RTE_CONF_PORT_SEL_CSR
, &result
);
61 if (CPS_DEFAULT_ROUTE
== (u8
)result
||
62 CPS_NO_ROUTE
== (u8
)result
)
63 *route_port
= RIO_INVALID_ROUTE
;
65 *route_port
= (u8
)result
;
72 idtcps_route_clr_table(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
77 if (table
== RIO_GLOBAL_TABLE
) {
78 for (i
= 0x80000000; i
<= 0x800000ff;) {
79 rio_mport_write_config_32(mport
, destid
, hopcount
,
80 RIO_STD_RTE_CONF_DESTID_SEL_CSR
, i
);
81 rio_mport_write_config_32(mport
, destid
, hopcount
,
82 RIO_STD_RTE_CONF_PORT_SEL_CSR
,
83 (CPS_DEFAULT_ROUTE
<< 24) |
84 (CPS_DEFAULT_ROUTE
<< 16) |
85 (CPS_DEFAULT_ROUTE
<< 8) | CPS_DEFAULT_ROUTE
);
94 idtcps_set_domain(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
98 * Switch domain configuration operates only at global level
100 rio_mport_write_config_32(mport
, destid
, hopcount
,
101 IDTCPS_RIO_DOMAIN
, (u32
)sw_domain
);
106 idtcps_get_domain(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
112 * Switch domain configuration operates only at global level
114 rio_mport_read_config_32(mport
, destid
, hopcount
,
115 IDTCPS_RIO_DOMAIN
, ®val
);
117 *sw_domain
= (u8
)(regval
& 0xff);
122 static struct rio_switch_ops idtcps_switch_ops
= {
123 .owner
= THIS_MODULE
,
124 .add_entry
= idtcps_route_add_entry
,
125 .get_entry
= idtcps_route_get_entry
,
126 .clr_table
= idtcps_route_clr_table
,
127 .set_domain
= idtcps_set_domain
,
128 .get_domain
= idtcps_get_domain
,
133 static int idtcps_probe(struct rio_dev
*rdev
, const struct rio_device_id
*id
)
135 pr_debug("RIO: %s for %s\n", __func__
, rio_name(rdev
));
137 spin_lock(&rdev
->rswitch
->lock
);
139 if (rdev
->rswitch
->ops
) {
140 spin_unlock(&rdev
->rswitch
->lock
);
144 rdev
->rswitch
->ops
= &idtcps_switch_ops
;
147 /* set TVAL = ~50us */
148 rio_write_config_32(rdev
,
149 rdev
->phys_efptr
+ RIO_PORT_LINKTO_CTL_CSR
, 0x8e << 8);
150 /* Ensure that default routing is disabled on startup */
151 rio_write_config_32(rdev
,
152 RIO_STD_RTE_DEFAULT_PORT
, CPS_NO_ROUTE
);
155 spin_unlock(&rdev
->rswitch
->lock
);
159 static void idtcps_remove(struct rio_dev
*rdev
)
161 pr_debug("RIO: %s for %s\n", __func__
, rio_name(rdev
));
162 spin_lock(&rdev
->rswitch
->lock
);
163 if (rdev
->rswitch
->ops
!= &idtcps_switch_ops
) {
164 spin_unlock(&rdev
->rswitch
->lock
);
167 rdev
->rswitch
->ops
= NULL
;
168 spin_unlock(&rdev
->rswitch
->lock
);
171 static const struct rio_device_id idtcps_id_table
[] = {
172 {RIO_DEVICE(RIO_DID_IDTCPS6Q
, RIO_VID_IDT
)},
173 {RIO_DEVICE(RIO_DID_IDTCPS8
, RIO_VID_IDT
)},
174 {RIO_DEVICE(RIO_DID_IDTCPS10Q
, RIO_VID_IDT
)},
175 {RIO_DEVICE(RIO_DID_IDTCPS12
, RIO_VID_IDT
)},
176 {RIO_DEVICE(RIO_DID_IDTCPS16
, RIO_VID_IDT
)},
177 {RIO_DEVICE(RIO_DID_IDT70K200
, RIO_VID_IDT
)},
178 { 0, } /* terminate list */
181 static struct rio_driver idtcps_driver
= {
183 .id_table
= idtcps_id_table
,
184 .probe
= idtcps_probe
,
185 .remove
= idtcps_remove
,
188 static int __init
idtcps_init(void)
190 return rio_register_driver(&idtcps_driver
);
193 static void __exit
idtcps_exit(void)
195 rio_unregister_driver(&idtcps_driver
);
198 device_initcall(idtcps_init
);
199 module_exit(idtcps_exit
);
201 MODULE_DESCRIPTION("IDT CPS Gen.1 Serial RapidIO switch family driver");
202 MODULE_AUTHOR("Integrated Device Technology, Inc.");
203 MODULE_LICENSE("GPL");