1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * IDT CPS RapidIO switches support
5 * Copyright 2009-2010 Integrated Device Technology, Inc.
6 * Alexandre Bounine <alexandre.bounine@idt.com>
10 #include <linux/rio_drv.h>
11 #include <linux/rio_ids.h>
12 #include <linux/module.h>
15 #define CPS_DEFAULT_ROUTE 0xde
16 #define CPS_NO_ROUTE 0xdf
18 #define IDTCPS_RIO_DOMAIN 0xf20020
21 idtcps_route_add_entry(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
22 u16 table
, u16 route_destid
, u8 route_port
)
26 if (route_port
== RIO_INVALID_ROUTE
)
27 route_port
= CPS_DEFAULT_ROUTE
;
29 if (table
== RIO_GLOBAL_TABLE
) {
30 rio_mport_write_config_32(mport
, destid
, hopcount
,
31 RIO_STD_RTE_CONF_DESTID_SEL_CSR
, route_destid
);
33 rio_mport_read_config_32(mport
, destid
, hopcount
,
34 RIO_STD_RTE_CONF_PORT_SEL_CSR
, &result
);
36 result
= (0xffffff00 & result
) | (u32
)route_port
;
37 rio_mport_write_config_32(mport
, destid
, hopcount
,
38 RIO_STD_RTE_CONF_PORT_SEL_CSR
, result
);
45 idtcps_route_get_entry(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
46 u16 table
, u16 route_destid
, u8
*route_port
)
50 if (table
== RIO_GLOBAL_TABLE
) {
51 rio_mport_write_config_32(mport
, destid
, hopcount
,
52 RIO_STD_RTE_CONF_DESTID_SEL_CSR
, route_destid
);
54 rio_mport_read_config_32(mport
, destid
, hopcount
,
55 RIO_STD_RTE_CONF_PORT_SEL_CSR
, &result
);
57 if (CPS_DEFAULT_ROUTE
== (u8
)result
||
58 CPS_NO_ROUTE
== (u8
)result
)
59 *route_port
= RIO_INVALID_ROUTE
;
61 *route_port
= (u8
)result
;
68 idtcps_route_clr_table(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
73 if (table
== RIO_GLOBAL_TABLE
) {
74 for (i
= 0x80000000; i
<= 0x800000ff;) {
75 rio_mport_write_config_32(mport
, destid
, hopcount
,
76 RIO_STD_RTE_CONF_DESTID_SEL_CSR
, i
);
77 rio_mport_write_config_32(mport
, destid
, hopcount
,
78 RIO_STD_RTE_CONF_PORT_SEL_CSR
,
79 (CPS_DEFAULT_ROUTE
<< 24) |
80 (CPS_DEFAULT_ROUTE
<< 16) |
81 (CPS_DEFAULT_ROUTE
<< 8) | CPS_DEFAULT_ROUTE
);
90 idtcps_set_domain(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
94 * Switch domain configuration operates only at global level
96 rio_mport_write_config_32(mport
, destid
, hopcount
,
97 IDTCPS_RIO_DOMAIN
, (u32
)sw_domain
);
102 idtcps_get_domain(struct rio_mport
*mport
, u16 destid
, u8 hopcount
,
108 * Switch domain configuration operates only at global level
110 rio_mport_read_config_32(mport
, destid
, hopcount
,
111 IDTCPS_RIO_DOMAIN
, ®val
);
113 *sw_domain
= (u8
)(regval
& 0xff);
118 static struct rio_switch_ops idtcps_switch_ops
= {
119 .owner
= THIS_MODULE
,
120 .add_entry
= idtcps_route_add_entry
,
121 .get_entry
= idtcps_route_get_entry
,
122 .clr_table
= idtcps_route_clr_table
,
123 .set_domain
= idtcps_set_domain
,
124 .get_domain
= idtcps_get_domain
,
129 static int idtcps_probe(struct rio_dev
*rdev
, const struct rio_device_id
*id
)
131 pr_debug("RIO: %s for %s\n", __func__
, rio_name(rdev
));
133 spin_lock(&rdev
->rswitch
->lock
);
135 if (rdev
->rswitch
->ops
) {
136 spin_unlock(&rdev
->rswitch
->lock
);
140 rdev
->rswitch
->ops
= &idtcps_switch_ops
;
143 /* set TVAL = ~50us */
144 rio_write_config_32(rdev
,
145 rdev
->phys_efptr
+ RIO_PORT_LINKTO_CTL_CSR
, 0x8e << 8);
146 /* Ensure that default routing is disabled on startup */
147 rio_write_config_32(rdev
,
148 RIO_STD_RTE_DEFAULT_PORT
, CPS_NO_ROUTE
);
151 spin_unlock(&rdev
->rswitch
->lock
);
155 static void idtcps_remove(struct rio_dev
*rdev
)
157 pr_debug("RIO: %s for %s\n", __func__
, rio_name(rdev
));
158 spin_lock(&rdev
->rswitch
->lock
);
159 if (rdev
->rswitch
->ops
!= &idtcps_switch_ops
) {
160 spin_unlock(&rdev
->rswitch
->lock
);
163 rdev
->rswitch
->ops
= NULL
;
164 spin_unlock(&rdev
->rswitch
->lock
);
167 static const struct rio_device_id idtcps_id_table
[] = {
168 {RIO_DEVICE(RIO_DID_IDTCPS6Q
, RIO_VID_IDT
)},
169 {RIO_DEVICE(RIO_DID_IDTCPS8
, RIO_VID_IDT
)},
170 {RIO_DEVICE(RIO_DID_IDTCPS10Q
, RIO_VID_IDT
)},
171 {RIO_DEVICE(RIO_DID_IDTCPS12
, RIO_VID_IDT
)},
172 {RIO_DEVICE(RIO_DID_IDTCPS16
, RIO_VID_IDT
)},
173 {RIO_DEVICE(RIO_DID_IDT70K200
, RIO_VID_IDT
)},
174 { 0, } /* terminate list */
177 static struct rio_driver idtcps_driver
= {
179 .id_table
= idtcps_id_table
,
180 .probe
= idtcps_probe
,
181 .remove
= idtcps_remove
,
184 static int __init
idtcps_init(void)
186 return rio_register_driver(&idtcps_driver
);
189 static void __exit
idtcps_exit(void)
191 rio_unregister_driver(&idtcps_driver
);
194 device_initcall(idtcps_init
);
195 module_exit(idtcps_exit
);
197 MODULE_DESCRIPTION("IDT CPS Gen.1 Serial RapidIO switch family driver");
198 MODULE_AUTHOR("Integrated Device Technology, Inc.");
199 MODULE_LICENSE("GPL");